最大流模板

题目描述
如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。
输入输出格式
输入格式:
第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)
输出格式:
一行,包含一个正整数,即为该网络的最大流。
输入输出样例
输入样例#14 5 4 3
4 2 30
4 3 20
2 3 20
2 1 30
1 3 40
输出样例#150
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=10,M<=25
对于70%的数据:N<=200,M<=1000
对于100%的数据:N<=10000,M<=100000
大部分题面

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N=1e5+10;
 5 struct node{
 6     int v,fl,ne;
 7 }e[N*2];
 8 int h[N],tot,n,m;
 9 void add1(int u,int v,int fl)
10 {
11     tot++;e[tot]=(node){v,fl,h[u]};h[u]=tot;
12 }
13 void add(int u,int v,int fl)
14 {
15     add1(u,v,fl);add1(v,u,0);
16 }
17 queue<int>q;
18 int d[N],S,T,H[N];
19 bool bfs()
20 {
21     for(int i=1;i<=n;++i) d[i]=0;
22     d[S]=1;q.push(S);
23     while(!q.empty())
24     {
25         int ff=q.front();q.pop();
26         for(int i=h[ff];i;i=e[i].ne)
27         {
28             int rr=e[i].v;
29             if(e[i].fl && !d[rr])
30              d[rr]=d[ff]+1,q.push(rr);
31         }
32     }
33     return d[T];
34 }
35 int dfs(int u,int fl)
36 {
37     if(u==T || fl==0) return fl;
38     int get=0,f;
39     for(int i=H[u];i;i=e[i].ne)
40     {
41         int rr=e[i].v;
42         if(e[i].fl && d[rr]==d[u]+1)
43         {
44             f=dfs(rr,min(fl,e[i].fl));
45             if(!f) continue;
46             get+=f;fl-=f;
47             e[i].fl-=f;e[i^1].fl+=f;
48             H[u]=i;
49             if(fl==0) break;
50         }
51     }
52     if(get==0) d[u]=0;
53     return get;
54 }
55 int main()
56 {
57     scanf("%d%d%d%d",&n,&m,&S,&T);
58     tot=1;
59     for(int i=1,x,y,z;i<=m;++i)
60     {
61         scanf("%d%d%d",&x,&y,&z);
62         add(x,y,z);
63     }
64     ll ans=0;
65     while(bfs())
66     {
67         for(int i=1;i<=n;++i) H[i]=h[i];
68         ans+=dfs(S,1e9);
69     }
70     cout<<ans;
71     return 0;
72 }
代码

 

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N=1e5+10;
 5 struct node{
 6     int u,v,fl,ne;
 7 }e[N*2];
 8 int h[N],tot,n,m;
 9 void add1(int u,int v,int fl)
10 {
11     tot++;e[tot]=(node){u,v,fl,h[u]};h[u]=tot;
12 }
13 void add(int u,int v,int fl)
14 {
15     add1(u,v,fl);add1(v,u,0);
16 }
17 queue<int>q;
18 int d[N],S,T,pre[N];
19 bool bfs()
20 {
21     for(int i=1;i<=n;++i) d[i]=0,pre[i]=0;
22     d[S]=1;q.push(S);
23     while(!q.empty())
24     {
25         int ff=q.front();q.pop();
26         for(int i=h[ff];i;i=e[i].ne)
27         {
28             int rr=e[i].v;
29             if(e[i].fl && !d[rr])
30             {
31                  d[rr]=d[ff]+1;pre[rr]=i;
32                  q.push(rr);
33             }
34         }
35     }
36     return d[T];
37 }
38 int main()
39 {
40     scanf("%d%d%d%d",&n,&m,&S,&T);
41     tot=1;
42     for(int i=1,x,y,z;i<=m;++i)
43     {
44         scanf("%d%d%d",&x,&y,&z);
45         add(x,y,z);
46     }
47     ll ans=0;
48     while(bfs())
49     {
50         int Min=1e9;
51         for(int i=T;i!=S;i=e[pre[i]].u)
52          Min=min(Min,e[pre[i]].fl);
53         for(int i=T;i!=S;i=e[pre[i]].u)
54          e[pre[i]].fl-=Min,e[pre[i]^1].fl+=Min;
55         ans+=Min;
56     }
57     cout<<ans;
58     return 0;
59 }
另一种非递归写法

 

posted @ 2018-04-02 21:39  月亮茶  阅读(179)  评论(0编辑  收藏  举报