POJ1325 Machine Schedule ——二分图最小覆盖——Pku1325

本文介绍如何利用二分图的最大匹配算法求解最小覆盖问题,并通过一个具体的编程实例进行说明。针对机器重启问题,建立了二分图模型,采用匈牙利算法实现了最大匹配,进而得出最小覆盖的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二分图最小覆盖:找到一个点集,使得每条边上至少有一个点在该集合中。

证明二分图最小覆盖=二分图最大匹配:

二分图最大匹配后,每个点都不能找到增广路,而找不到增广路的原因就是至少有一个点已经被匹配了。即这个点在二分图的最大匹配中。而二分图最大匹配中会存在同一条边两个点都在这个点集中的情况,我们只要取一个点即可。

 

本题当中,将机器A上的模式看作X集合,机器B上的模式看作Y集合,每个任务对应一条边,两点分别为在A,B上的模式,建立二分图。可以看出,最小的重新启动次数就是二分图的最小覆盖——即最大匹配。普通匈牙利算法即可。


Hint:注意一点:读入时要加上这样一句话,否则会WA:

if p*q=0 then continue;

 

CODE

Program POJ1325;//By_Thispoet
Const
	maxn=100;
Var
	i,j,m,n,p,q,k,ans					:Longint;
	pre,other,last						:Array[0..maxn*10]of Longint;
	res									:Array[0..maxn]of Longint;
	state								:Array[0..maxn]of Boolean;

Function Dfs(i:Longint):Boolean;
var j,k:Longint;
begin
	j:=last[i];
	while j<>0 do
		begin
			k:=other[j];
			if not state[k] then
				begin
					state[k]:=true;
					if (res[k]=0)or(Dfs(res[k]))then
						begin
							res[k]:=i;
							exit(true);
						end;
				end;
			j:=pre[j];
		end;
	exit(false);
end;


BEGIN

	readln(n,m,k);
	while n<>0 do 
		begin
		
			fillchar(last,sizeof(last),0);
			for i:=1 to k do
				begin
					readln(j,p,q);
					if p*q=0 then continue;
					pre[i]:=last[p];last[p]:=i;other[i]:=q;
				end;

			ans:=0;
			fillchar(res,sizeof(res),0);
			for i:=1 to n do
				begin
					fillchar(state,sizeof(state),0);
					if Dfs(i) then inc(ans);
				end;
			
			writeln(ans);
			
			read(n);
			if n<>0 then readln(m,k);
			
		end;

END.

转载于:https://www.cnblogs.com/Thispoet/archive/2011/09/14/2175399.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值