• 二分图最大权匹配模板(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.
  • 相关阅读:
    数据库(六):多表关系
    数据库(五):约束关系
    数据库(四):数据类型
    数据库(三):存储引擎
    数据库(二):初识sql语句
    数据库(一):初识数据库
    番外:socketserver用法
    ~~并发编程(十六):协程理论~~
    ~~并发编程(十五):进程池线程池~~
    ~~并发编程(十四):Queue~~
  • 原文地址:https://www.cnblogs.com/Currier/p/6702024.html
Copyright © 2020-2023  润新知