【BZOJ3396】【Usaco2009 Jan】Total flow 水流

【Description】

  
  


【Input】

   第1行输入N,之后N行每行描述一条水管,前两个英文字母表示水管的两端(大小写字母是不一样的),后一个整数表示水管的流量,流量不会超过1000.


【Output】

   一个整数,表示总流量.


【Sample Input】

5
A B 3
B C 3
C D 5
D Z 4
B Z 6

【Sample Output】

3

【Solution】

  裸的最大流。学习了新的姿势:ISAP,竟然刷到了Rank2。
  
  代码如下:

/**************************************************************
    Problem: 3396
    User: llgyc
    Language: Pascal
    Result: Accepted
    Time:0 ms
    Memory:248 kb
****************************************************************/

const inf = maxlongint shr 1; maxn = 55;
type etype = record
               from,go,val,next:longint;
             end;
var n,cnt,ans:longint;
    head,cur,gap,d,p:array[0..maxn] of longint;
    e:array[0..1405] of etype;
function min(x,y:longint):longint;
  begin if x<y then exit(x) else exit(y); end;
procedure ins(u,v,w:longint);
  begin inc(cnt); e[cnt].from:=u; e[cnt].go:=v; e[cnt].val:=w; e[cnt].next:=head[u]; head[u]:=cnt; end;
procedure insert(u,v,w:longint);
  begin ins(u,v,w); ins(v,u,0); end;
function get():longint;
  var c,t:char;
  begin
    read(c); read(t);
    if (c in ['a'..'z']) then exit(ord(c)-ord('a')+27) else exit(ord(c)-ord('A')+1);
  end;
procedure init();
  var i,u,v,w:longint;
  begin
    readln(n); cnt:=1;
    for i:=1 to n do begin
      u:=get(); v:=get(); readln(w);
      insert(u,v,w);
    end;
  end;
function isap():longint;
  var i,s,t,u,flow,f:longint;
  begin
    for i:=1 to maxn do cur[i]:=head[i];
    gap[0]:=maxn;
    s:=1; t:=26; u:=1; flow:=0;
    while d[s]<maxn do begin
      i:=cur[u];
      while (i<>0) do begin
        if (d[u]=d[e[i].go]+1) and (e[i].val>0) then break;
        i:=e[i].next;
      end;
      if i<>0 then begin
        p[e[i].go]:=i; cur[u]:=i; u:=e[i].go;
        if u=t then begin
          f:=inf;
          while u<>s do begin
            f:=min(f,e[p[u]].val);
            u:=e[p[u]].from;
          end;
          u:=t;
          while u<>s do begin
            dec(e[p[u]].val,f); inc(e[p[u] xor 1].val,f);
            u:=e[p[u]].from;
          end;
          inc(flow,f);
        end;
      end
      else begin
        dec(gap[d[u]]); if gap[d[u]]=0 then break;
        d[u]:=maxn;
        cur[u]:=head[u]; i:=head[u];
        while i<>0 do begin
          if (e[i].val>0) and (d[u]>d[e[i].go]+1) then d[u]:=d[e[i].go]+1;
          i:=e[i].next;
        end;
        inc(gap[d[u]]);
        if u<>s then u:=e[p[u]].from;
      end;
    end;
    exit(flow);
  end;
begin
  init();
  ans:=isap();
  writeln(ans);
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值