如果发现广告等破坏行为,请尽量将条目恢复到较早的版本而不是把相应内容直接删除,谢谢合作。

Hopcroft Karp算法

来自"NOCOW"

跳转到: 导航, 搜索

匈牙利算法中,我们每次寻找一条增广路来增加匹配集合M.可以证明,每次找增广路的复杂度是O(E),一共需要增广O(V)次,因此总时间复杂度为O(VE).为了降低时间复杂度,在Hopcroft Karp算法中,我们在增加匹配集合M时,每次寻找多条增广路.可以证明,这样迭代次数最多为2*V^0.5,所以,时间复杂度就降到了O(V^0.5*E).

该算法由John E.Hopcroft和Richard M.Karp于1973年提出,故称Hopcroft Karp算法.

program Project1;
  const maxn=1000;
  var dx,dy,mx,my,q:array[1..maxn]of longint;
      adj:array[1..maxn,0..maxn]of longint;
      n,m,e,i,j,ans,ff,rr:longint;
  function bfs:boolean;
    var i,u,j:longint;
    begin
      bfs:=false;
      fillchar(q,sizeof(q),0);
      rr:=1;
      ff:=1;
      for i:=1 to n do
        if mx[i]=-1
          then begin
            q[ff]:=i;
            inc(ff);
          end;
      for i:=1 to max(m,n)do
        begin
          dx[i]:=0;
          dy[i]:=0;
        end;
      while rr<ff do
        begin
          u:=q[rr];
          inc(rr);
          for j:=1 to adj[u][0]do
            begin
              i:=adj[u][j];
              if dy[i]=0
                then begin
                  dy[i]:=dx[u]+1;
                  if my[i]=-1
                    then bfs:=true
                    else begin
                      dx[my[i]]:=dy[i]+1;
                      q[ff]:=my[i];
                      inc(ff);
                    end;
                end;
            end;
        end;
    end;
  function dfs(x:longint):boolean;
    var i,j:longint;
    begin
      for j:=1 to adj[x][0]do
        begin
          i:=adj[x][j];
          if dy[i]=dx[x]+1
            then begin
              dy[i]:=0;
              if(my[i]=-1)or dfs(my[i])
                then begin
                  mx[x]:=i;
                  my[i]:=x;
                  exit(true);
                end;
            end;
        end;
      exit(false);
    end;
  begin
    readln(n,m,e);
    for i:=1 to e do
      begin
        readln(ff,rr);
        inc(adj[ff][0]);
        adj[ff][adj[ff][0]]:=rr;
      end;
    for i:=1 to n do
      begin
        mx[i]:=-1;
        my[i]:=-1;
      end;
    ans:=0;
    while bfs do
      for i:=1 to n do
        if(mx[i]=-1)and(dfs(i))
          then inc(ans);
    writeln(ans);
  end.
个人工具