原来想随便找个最大流的题目练练手的,根据别人的列表在POJ上找了一道题,花了好长时间看懂了题目,然后想了一天,不想却碰到了新的知识,而且很多地方都有讲解。
题目:POJ1325
题解:左边是机器A的模式,右边是机器B的模式,用任务来连接这些模式,即某个任务可以用左边的模式a或者右边的模式b来做,那么就a连接b。我们的目的是找出最小的点集能保证任意的一个任务,都能有对应的模式。
算法:最小点覆盖数=二分图最大匹配数 匈牙利可秒之
体会:我傻X了,一个匈牙利总是在细节出错,而且变量没有每次初始化,在POJ上WA了好几次
参考资料:
《算法艺术与信息学竞赛》P331
《组合数学》(Richard A.Brualdi 机械工业出版社 原书第四版)P232
Matrix67 二分图最大匹配的König定理及其证明
代码:
var a:array[0..1000,0..1000] of boolean; i,j,k,m,n,ans,p,x,y:longint; flag:array[0..1000] of boolean; link:array[0..1000] of longint; function dfs(k:longint):boolean; var i,j:longint; begin for i:=1 to n+m do if a[k,i] and not flag[i] then begin flag[i]:=true; if (link[i]=0) or dfs(link[i]) then begin link[i]:=k; exit(true); end; end; exit(false); end; begin while not eof do begin read(n); if n=0 then break; readln(m,k); fillchar(link,sizeof(link),0); fillchar(a,sizeof(a),0); for i:=1 to k do begin readln(j,x,y); if (x<>0)and(y<>0) then a[x,n+y]:=true; end; ans:=0; for i:=1 to n+m do begin fillchar(flag,sizeof(flag),0); if dfs(i) then inc(ans); end; writeln(ans); end; end.