zoukankan      html  css  js  c++  java
  • 二分图最大权匹配模板(pascal)

    用uoj80的题面了:

    从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生。编号分别为 1,,nl1,…,nl 和 1,,nr1,…,nr。

    有若干个这样的条件:第 vv 个男生和第 uu 个女生愿意结为配偶,且结为配偶后幸福程度为 ww。

    请问这个班级里幸福程度之和最大是多少?

    输入格式

    第一行三个正整数,nl,nr,mnl,nr,m。

    接下来 mm 行,每行三个整数 v,u,wv,u,w 表示第 vv 个男生和第 uu 个女生愿意结为配偶,且幸福程度为 ww。保证 1vnl1≤v≤nl,1unr1≤u≤nr,保证同一对 v,uv,u 不会出现两次。

    输出格式

    第一行一个整数,表示幸福程度之和的最大值。

    接下来一行 nlnl 个整数,描述一组最优方案。第 vv 个整数表示 vv 号男生的配偶的编号。如果 vv 号男生没配偶请输出 00。

    样例一

    input

    2 2 3
    1 1 100
    1 2 1
    2 1 1
    
    

    output

    100
    1 0
    
    

    限制与约定

    1≤nl,nr≤400,1≤m≤160000,1w109

    时间限制1s1s

    空间限制256MB

    一种简单一点的方法就是最大费用流或者用相反数作为费用跑最小费用流,但是比km算法慢。

    但实现时要注意不是求最大费用最大流,而是当最长增广路<=0时就停止。

    这个代码在uoj是tle的,那个好像必须用km,但我不会啦。

     1 program rrr(input,output);
     2 const
     3   inf=123456789012345;
     4 type
     5   etype=record
     6      t,c,next,rev:longint;
     7      w:int64;
     8   end;
     9 var
    10   e:array[0..400040]of etype;
    11   a,frv,fre:array[-440..440]of longint;
    12   inq:array[-440..440]of boolean;
    13   dis:array[-440..440]of int64;
    14   q:array[0..1000]of longint;
    15   nl,nr,m,i,x,y,cnt,j,h,t:longint;
    16   ans,w,f:int64;
    17 function min(a,b:longint):longint;
    18 begin
    19    if a<b then exit(a) else exit(b);
    20 end;
    21 procedure ins(x,y,c:longint;w:int64);
    22 begin
    23    inc(cnt);e[cnt].t:=y;e[cnt].c:=c;e[cnt].w:=w;e[cnt].next:=a[x];a[x]:=cnt;
    24 end;
    25 procedure add(x,y,c:longint;w:int64);
    26 begin
    27    ins(x,y,c,w);e[cnt].rev:=cnt+1;ins(y,x,0,-w);e[cnt].rev:=cnt-1;
    28 end;
    29 procedure spfa;
    30 begin
    31    for i:=-nl to nr+1 do begin dis[i]:=-inf;inq[i]:=false; end;
    32    h:=0;t:=1;q[1]:=0;dis[0]:=0;inq[0]:=true;
    33    while h<>t do
    34       begin
    35          inc(h);if h>1000 then h:=1;
    36          i:=a[q[h]];
    37          while i<>0 do
    38             begin
    39                if (e[i].c>0) and (dis[q[h]]+e[i].w>dis[e[i].t]) then
    40                   begin
    41                      dis[e[i].t]:=dis[q[h]]+e[i].w;
    42                      fre[e[i].t]:=i;frv[e[i].t]:=q[h];
    43                      if not inq[e[i].t] then
    44                         begin
    45                            inc(t);if t>1000 then t:=1;
    46                            q[t]:=e[i].t;inq[e[i].t]:=true;
    47                         end;
    48                   end;
    49                i:=e[i].next;
    50             end;
    51          inq[q[h]]:=false;
    52       end;
    53 end;
    54 begin
    55    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
    56    readln(nl,nr,m);
    57    fillchar(a,sizeof(a),0);cnt:=0;
    58    for i:=1 to nl do add(0,-i,1,0);
    59    for i:=1 to nr do add(i,nr+1,1,0);
    60    for i:=1 to m do begin readln(x,y,w);add(-x,y,1,w); end;
    61    ans:=0;
    62    while true do
    63       begin
    64          spfa;
    65          if dis[nr+1]<=0 then break;
    66          i:=nr+1;f:=1000;w:=0;
    67          while i<>0 do begin f:=min(f,e[fre[i]].c);i:=frv[i]; end;
    68          ans:=ans+dis[nr+1]*f;
    69          i:=nr+1;while i<>0 do begin dec(e[fre[i]].c,f);inc(e[e[fre[i]].rev].c,f);i:=frv[i]; end;
    70       end;
    71    writeln(ans);
    72    for i:=1 to nl do
    73       begin
    74          j:=a[-i];
    75          while j<>0 do begin if e[j].c=0 then break;j:=e[j].next; end;
    76          if j=0 then write(0,' ') else write(e[j].t,' ');
    77       end;
    78    close(input);close(output);
    79 end.
  • 相关阅读:
    不用写代码的框架
    bat执行python脚本,执行多条命令
    VMware-workstation-full-15.1.0-13591040安装破解-附件密钥
    w10谷歌chrome关闭自动更新
    谷歌安装提示已经安装高版本解决
    python项目三方库导出导入 requirements.txt文件
    点阴影
    goto gamedev blog
    20135315-信息安全系统设计基础第五周学习总结
    win10 +python3.6环境下安装opencv以及pycharm导入cv2有问题的解决办法
  • 原文地址:https://www.cnblogs.com/Currier/p/6702024.html
Copyright © 2011-2022 走看看