帶權二分圖匹配:KM演算法與費用流建模

來源:互聯網
上載者:User

KM似乎還是有點難以理解,看了半天資料仍有半懂不懂的感覺,或許以後多想想、畫畫,做些題能加深理解吧,當初學匈牙利的時候就是這樣。

相關資料

二分圖帶權匹配 KM演算法與費用流模型建立

丘位元的問題——求二分圖最大權匹配的演算法

nocow上的講解

題目:ural1076

原題:http://acm.timus.ru/problem.aspx?space=1&num=1076

譯題:http://www.nocow.cn/index.php/Translate:URAL/1076

題解:http://www.nocow.cn/index.php/URAL/1076

我的KM是抄nocow上的題解的,只不過出於習慣改了一個變數名。費用流的思路也是按nocow上的,計算出i種箱子裝j種垃圾的費用然後求最小費用。根據自己的理解按照KM上的統計所有垃圾量-最大費用的程式也寫了一個,不過陷入死迴圈中,有時間再調試吧。

我的ural1076 KM演算法程式

const  oo=199305080;  maxn=200;var  lx,ly,link:array[0..maxn] of longint;  w:array[0..maxn,0..maxn] of longint;  i,j,k,m,n,d,tot:longint;  x,y:array[0..maxn] of boolean;function max(a,b:longint):longint;begin  if a<b then exit(B) else exit(a);end;procedure init;begin  readln(n);  for i:=1 to n do    for j:=1 to n do    begin      read(w[i,j]);      inc(tot,w[i,j]);    end;end;function dfs(v:longint):boolean;var  i:longint;begin  if v=0 then exit(true);  x[v]:=true;  for i:=1 to n do    if (y[i]=false) and (lx[v]+ly[i]=w[v,i]) then    begin      y[i]:=true;      if dfs(link[i]) then      begin        link[i]:=v;        exit(true);      end    end;  exit(false);end;procedure main;begin  for i:=1 to n do    for j:=1 to n do      lx[i]:=max(lx[i],w[i,j]);  for k:=1 to n do    while true do    begin      fillchar(x,sizeof(x),0);      fillchar(y,sizeof(y),0);      if dfs(k) then break;      d:=oo;      for i:=1 to n do        if x[i] then          for j:=1 to n do            if (not y[j]) and (lx[i]+ly[j]-w[i,j]<d) then               d:=lx[i]+ly[j]-w[i,j];      for i:=1 to n do      begin        if x[i] then dec(lx[i],d);        if y[i] then inc(ly[i],d);      end    end;end;procedure print;begin  for i:=1 to n do    dec(tot,w[link[i],i]);  writeln(tot);end;begin  init;  main;  print;end.來一個費用流:
const  maxn=400;  oo=199305080;var  c,cost,w:array[0..maxn,0..maxn] of longint;  flow,i,j,k,m,n,mincost,tot,s,t,pre,now,sum:longint;  path:array[0..maxn] of longint;  q,dist:array[0..100000] of longint;  flag:array[0..10000] of boolean;function spfa:boolean;var  i,j,k,head,tail:longint;begin  head:=0;  tail:=1;  q[1]:=s;  fillchar(flag,sizeof(flag),0);  flag[s]:=true;  for i:=1 to tot do    dist[i]:=oo;  dist[s]:=0;  while head<tail do  begin    inc(head);    i:=q[head];    flag[i]:=false;    for j:=1 to tot do    begin      if (c[i,j]>0) and (dist[j]>dist[i]+cost[i,j]) then      begin        dist[j]:=dist[i]+cost[i,j];        path[j]:=i;        if not flag[j] then        begin          flag[j]:=true;          inc(tail);          q[tail]:=j;        end;      end;    end;  end;  exit(dist[t]<>oo);end;procedure init;begin  readln(n);  for i:=1 to n do  begin    sum:=0;    for j:=1 to n do    begin      read(w[i,n+j]);      inc(sum,w[i,n+j]);    end;    for j:=1 to n do    begin      cost[i,n+j]:=sum-w[i,n+j];      cost[n+j,i]:=-cost[i,n+j];      c[i,n+j]:=1;    end;  end;  s:=n*2+1;  t:=n*2+2;  tot:=t;  for i:=1 to n do    c[s,i]:=1;  for i:=1 to n do    c[n+i,t]:=1;end;function min(a,b:longint):longint;begin  if a<b then exit(a) else exit(b);end;procedure main;begin  while spfa do  begin    now:=t;    flow:=oo;    while now<>s do    begin      pre:=path[now];      flow:=min(flow,c[pre,now]);      now:=pre;    end;    now:=t;    while now<>s do    begin      pre:=path[now];      dec(c[pre,now],flow);      inc(c[now,pre],flow);      inc(mincost,flow*cost[pre,now]);      now:=pre;    end;  end;end;procedure print;begin  writeln(mincost);end;begin  init;  main;  print;end.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.