跳至內容

英文维基 | 中文维基 | 日文维基 | 草榴社区

霍普克洛夫特-卡普演算法

本頁使用了標題或全文手工轉換
維基百科,自由的百科全書

霍普克洛夫特-卡普演算法Hopcroft Karp演算法)是用來解決二分圖最大匹配問題的一種演算法。

匈牙利演算法中,我們每次尋找一條增廣路來增加匹配集合M。可以證明,每次找增廣路的複雜度是,一共需要增廣次,因此總時間複雜度為。為了降低時間複雜度,在霍普克洛夫特-卡普演算法中,我們在增加匹配集合M時,每次尋找多條增廣路。可以證明,這樣迭代次數最多為,所以,時間複雜度就降到了

該演算法由約翰·霍普克洛夫特理查德·卡普於1973年提出。

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 n do dx[i]:=0;
      for i:=1 to m do dy[i]:=0;
      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 mx[i]:=-1;
    for i:=1 to m do my[i]:=-1;
    ans:=0;
    while bfs do
      for i:=1 to n do
        if(mx[i]=-1)and(dfs(i))
          then inc(ans);
    writeln(ans);
  end.