最大网络流

深搜网络流+当前弧优化

 1 const
 2   inf=1000000000;
 3 type
 4   rec=record
 5     s,e,w,next:longint;
 6   end;
 7 var
 8   b,bb,d,q:array[-1..300001] of longint;
 9   a:array[-1..1000001] of rec;
10   n,m,i,j,k,l,st,ed,ww,top,ans,nn,dd,x:longint;
11 function min(aa,bb:longint):longint;
12 begin
13   if aa<bb then exit(aa);exit(bb);
14 end;
15 procedure add(st,ed,ww:longint);
16 begin
17   inc(top);
18   a[top].s:=st;
19   a[top].e:=ed;
20   a[top].w:=ww;
21   a[top].next:=b[st];
22   b[st]:=top;
23 end;
24 function addflow(p,maxflow:longint):longint;
25 var
26   o,u:longint;
27 begin
28   if(p=ed)or(maxflow=0)then exit(maxflow);
29   d[p]:=1;
30   addflow:=0; u:=bb[p];
31   while u>0 do
32   begin
33     if(a[u].w>0)and(d[a[u].e]=0)then
34     begin
35       o:=addflow(a[u].e,min(maxflow,a[u].w));
36       if o>0 then
37       begin
38         dec(a[u].w,o); if a[u].w>0 then bb[p]:=u;
39         inc(a[u xor 1].w,o);
40         dec(maxflow,o); inc(addflow,o);
41         if maxflow=0 then break;
42       end;
43     end;
44     u:=a[u].next;
45   end;
46 end;
47 function network:longint;
48 var i,last:longint;
49 begin
50   network:=0; last:=0;
51   while true do
52   begin
53     for i:=st to ed do begin bb[i]:=b[i]; d[i]:=0; end;
54     inc(network,addflow(st,inf));
55     if network=last then exit;
56     last:=network;
57   end;
58 end;
59 begin
60   readln(n,m);
61   top:=1; build;
62   writeln(network);
63 end.
View Code

 

DINIC网络流+当前弧优化

 1 const
 2   inf=1000000000;
 3 type
 4   rec=record
 5     s,e,w,next:longint;
 6   end;
 7 var
 8   b,bb,d,q:array[-1..300001] of longint;
 9   a:array[-1..1000001] of rec;
10   n,m,i,j,k,l,st,ed,ww,top,ans,nn,dd,x:longint;
11 function min(aa,bb:longint):longint;
12 begin
13   if aa<bb then exit(aa);exit(bb);
14 end;
15 procedure add(st,ed,ww:longint);
16 begin
17   inc(top);
18   a[top].s:=st;
19   a[top].e:=ed;
20   a[top].w:=ww;
21   a[top].next:=b[st];
22   b[st]:=top;
23 end;
24 function bfs:boolean;
25 var head,tail,x,u,i:longint;
26   y:rec;
27 begin
28   for i:=st to ed do d[i]:=-1;
29   tail:=1; head:=0; d[st]:=0; q[1]:=st;
30   while head<tail do
31   begin
32     inc(head); x:=q[head];
33     u:=b[x];
34     while u>0 do
35     begin
36       y:=a[u];
37       if(d[y.e]=-1)and(y.w>0)then
38       begin
39         d[y.e]:=d[x]+1;
40         inc(tail); q[tail]:=y.e;
41       end;
42       u:=y.next;
43     end;
44   end;
45   if d[ed]=-1 then exit(false);
46   exit(true);
47 end;
48 function addflow(p,maxflow:longint):longint;
49 var
50   o,u:longint;
51 begin
52   if(p=ed)or(maxflow=0)then exit(maxflow);
53   addflow:=0; u:=bb[p];
54   while u>0 do
55   begin
56     if(d[a[u].e]=d[p]+1)and(a[u].w>0)then
57     begin
58       o:=addflow(a[u].e,min(maxflow,a[u].w));
59       if o>0 then
60       begin
61         dec(a[u].w,o); if a[u].w>0 then bb[p]:=u;
62         inc(a[u xor 1].w,o);
63         dec(maxflow,o); inc(addflow,o);
64         if maxflow=0 then break;
65       end;
66     end;
67     u:=a[u].next;
68   end;
69   if addflow=0 then d[p]:=-1;
70 end;
71 function network:longint;
72 var i:longint;
73 begin
74   network:=0;
75   while bfs do
76   begin
77     for i:=st to ed do bb[i]:=b[i];
78     inc(network,addflow(st,inf));
79   end;
80 end;
81 begin
82   readln(n,m);
83   top:=1; build;
84   writeln(network);
85 end.
PASCAL
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int INF=1000000000;
 4 int n,m,ss,tt,flow,l,r,lb[100005];
 5 int c[100005],c2[100005],b[300005][3],dis[100005];
 6 void adedg(int x,int y,int z)
 7 {
 8     m++; b[m][0]=z; b[m][1]=y; b[m][2]=c[x]; c[x]=m;
 9     m++; b[m][0]=0; b[m][1]=x; b[m][2]=c[y]; c[y]=m;
10 }
11 bool bfs()
12 {
13     for(int i=ss;i<=tt;i++)dis[i]=-1; dis[ss]=0;
14     l=0; r=1; lb[r]=ss;
15     while(l<r)
16     {
17         l++; int x=lb[l];
18         for(int i=c[x];i;i=b[i][2])
19         if((dis[b[i][1]]==-1)and(b[i][0]>0))
20         { dis[b[i][1]]=dis[x]+1; r++; lb[r]=b[i][1]; }
21     }
22     if(dis[tt]!=-1)return 1;
23     return 0;
24 }
25 int work(int x,int ma)
26 {
27     if((ma==0)or(x==tt))return ma;
28     int add=0;
29     while(c2[x])
30     {
31         int i=c2[x];
32         if(dis[b[i][1]]==dis[x]+1)
33         {
34             int l=work(b[i][1],min(b[i][0],ma)); add+=l; ma-=l;
35             b[i][0]-=l; b[i^1][0]+=l;
36             if(ma==0)return add;
37         }
38         c2[x]=b[c2[x]][2];
39     }
40     return add;
41 }
42 int main()
43 {
44     m=1; build(); 
45     flow=0;
46     while(bfs())
47     {
48         for(int i=ss;i<=tt;i++)c2[i]=c[i];
49         flow+=work(ss,INF);
50     }
51     printf("%d\n",flow);
52 }
C++

转载于:https://www.cnblogs.com/GhostReach/p/6252734.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值