二分图匹配之匈牙利算法和 二分图匹配的几种题型

首先介绍匈牙利算法。

如果一个二分图有增广路(交错路),那么每次可以通过取反使得匹配数多一条。

匈牙利算法就是不断求增广路直到没有增广路可求,即最大匹配。

程序实现:

program hungray;
var map:array[1..500,1..500]of byte;//邻接表
    r,c,n,k,i,ans:longint;
    start:array[1..500]of boolean;//每次更新访问的节点,如果对于同一种情况某节点被访问过,就不用再访问了
    resul:array[1..500]of longint;//最终结果,每次更新
function dfs(x:longint):boolean;//匈牙利
var i:longint;
begin
 for i:=1 to n do
  if (map[x,i]=1)and(not start[i]) then
   begin
    start[i]:=true;//如果访问过,无论怎样都记录过了,防止超时。标记访问
    if (resul[i]=0)or(dfs(resul[i])) then//如果该点没有访问过,或者可以找到增广路,就返回真
     begin
      resul[i]:=x;//更改新路径
      dfs:=true;
      exit;//注意得出结果及时退出
     end;
   end;
 dfs:=false;
end;
begin
 read(n,k);
 for i:=1 to k do
  begin
   read(r,c);
   map[r,c]:=1;
  end;
 ans:=0;
 for i:=1 to n do//枚举X集合的点
  begin
   fillchar(start,sizeof(start),false);
   if dfs(i) then ans:=ans+1;
  end;
 write(ans);
end.

几种重要应用:

①最小点集覆盖问题:最小点覆盖=最大匹配

 通常需要将网格中的行和列分别分为两个点集,某行某列如果有点则连一条边(可看成有向边),做最大匹配

②最小路径覆盖:将出度入度匹配(两点相连即连两点)


你可能感兴趣的:(匈牙利算法)