洛谷 P3376 【【模板】网络最大流】

题目描述

如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。

输入

第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。

接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)

输出

一行,包含一个正整数,即为该网络的最大流。

样例输入

4 5 4 3
4 2 30
4 3 20
2 3 20
2 1 30
1 3 40

样例输出

50

数据规模:

对于30%的数据:N<=10,M<=25

对于70%的数据:N<=200,M<=1000

对于100%的数据:N<=10000,M<=100000

网络流的模板题。汇总一些增广路算法。(Ford-Fulkerson, Edmond-Karp, Dinic, ISAP)

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 #include <queue>
  6 using namespace std;
  7 
  8 struct edge {
  9     int to,cap,rev;
 10 };
 11 
 12 const int maxn=10001, INF=0x7F7F7F7F;
 13 int n,m;
 14 vector <edge> G[maxn+1];
 15 
 16 edge make_edge(int to, int cap, int rev) {
 17     edge x;
 18     x.to=to, x.cap=cap, x.rev=rev;
 19     return x;
 20 }
 21 
 22 void add_edge(int from, int to, int cap) {
 23     G[from].push_back(make_edge(to,cap,G[to].size()));
 24     G[to].push_back(make_edge(from,0,G[from].size()-1));
 25 }
 26 
 27 void init() {
 28     for (int i=1; i<=m; i++) {
 29         int u,v,w;
 30         scanf("%d%d%d",&u,&v,&w);
 31         add_edge(u,v,w);
 32     }
 33 }
 34 
 35 namespace Ford_Fulkerson {
 36     bool used[maxn+1];
 37 
 38     int dfs(int x, int t, int f) {
 39         if (x==t) return f;
 40         used[x]=true;
 41         for (int i=0; i<G[x].size(); i++) {
 42             edge &e=G[x][i];
 43             if (!used[e.to]&&e.cap>0) {
 44                 int d=dfs(e.to,t,min(f,e.cap));
 45                 if (d>0) {
 46                     e.cap-=d;
 47                     G[e.to][e.rev].cap+=d;
 48                     return d;
 49                 }
 50             }
 51         }
 52         return 0;
 53     }
 54 
 55     int max_flow(int s, int t) {
 56         int flow=0;
 57         for(;;) {
 58             memset(used,0,sizeof(used));
 59             int f=dfs(s,t,INF);
 60             if (f==0) return flow;
 61             flow+=f;
 62         }
 63     }
 64 }
 65 
 66 namespace Edmond_Karp {
 67     bool vis[maxn+1];
 68     int prev[maxn+1];
 69     int pree[maxn+1];
 70 
 71     void bfs(int s) {
 72         memset(vis,0,sizeof(vis));
 73         memset(prev,-1,sizeof(prev));
 74         memset(pree,-1,sizeof(pree));
 75         queue <int> q;
 76         vis[s]=true;
 77         q.push(s);
 78 
 79         while(!q.empty()) {
 80             int x=q.front();
 81             q.pop();
 82             for (int i=0; i<G[x].size(); i++) {
 83                 edge &e=G[x][i];
 84                 if (e.cap>0&&!vis[e.to]) {
 85                     prev[e.to]=x;
 86                     pree[e.to]=i;
 87                     vis[e.to]=true;
 88                     q.push(e.to);
 89                 }
 90             }
 91         }
 92     }
 93 
 94     int max_flow(int s, int t) {
 95         int flow=0;
 96         for(;;) {
 97             bfs(s);
 98             if (!vis[t]) return flow;
 99             int d=INF;
100             for (int i=t; prev[i]!=-1; i=prev[i])
101                 d=min(d,G[prev[i]][pree[i]].cap);
102             for (int i=t; prev[i]!=-1; i=prev[i]) {
103                 edge &e=G[prev[i]][pree[i]];
104                 e.cap-=d;
105                 G[e.to][e.rev].cap+=d;
106             }
107             flow+=d;
108         }
109     }
110 }
111 
112 namespace Dinic {
113     int level[maxn+1];
114     int iter[maxn+1];
115 
116     void bfs(int s) {
117         memset(level,-1,sizeof(level));
118         queue <int> q;
119         level[s]=0;
120         q.push(s);
121 
122         while (!q.empty()) {
123             int x=q.front();
124             q.pop();
125             for (int i=0; i<G[x].size(); i++) {
126                 edge &e=G[x][i];
127                 if (e.cap>0&&level[e.to]<0) {
128                     level[e.to]=level[x]+1;
129                     q.push(e.to);
130                 }
131             }
132         }
133     }
134 
135     int dfs(int x, int t, int f) {
136         if (x==t) return f;
137         for (int &i=iter[x]; i<G[x].size(); i++) {
138             edge &e=G[x][i];
139             if (e.cap>0&&level[e.to]>level[x]) {
140                 int d=dfs(e.to,t,min(f,e.cap));
141                 if (d>0) {
142                     e.cap-=d;
143                     G[e.to][e.rev].cap+=d;
144                     return d;
145                 }
146             }
147         }
148         return 0;
149     }
150 
151     int max_flow(int s, int t) {
152         int flow=0;
153         for(;;) {
154             bfs(s);
155             if (level[t]<0) return flow;
156             memset(iter,0,sizeof(iter));
157             int f;
158             while ((f=dfs(s,t,INF))>0)
159                 flow+=f;
160         }
161     }
162 }
163 
164 namespace ISAP {
165     int gap[maxn+1];
166     int iter[maxn+1];
167     int level[maxn+1];
168 
169     void bfs(int t) {
170         memset(gap,0,sizeof(gap));
171         memset(level,-1,sizeof(level));
172         queue <int> q;
173         level[t]=1;
174         gap[level[t]]=1;
175         q.push(t);
176 
177         while (!q.empty()) {
178             int x=q.front();
179             q.pop();
180             for (int i=0; i<G[x].size(); i++) {
181                 edge &e=G[x][i];
182                 if (level[e.to]<0) {
183                     level[e.to]=level[x]+1;
184                     gap[level[e.to]]++;
185                     q.push(e.to);
186                 }
187             }
188         }
189     }
190 
191     int dfs(int x, int s, int t, int f) {
192         if (x==t) return f;
193         int flow=0;
194         for (int &i=iter[x]; i<G[x].size(); i++) {
195             edge &e=G[x][i];
196             if (e.cap>0&&level[x]==level[e.to]+1) {
197                 int d=dfs(e.to,s,t,min(f-flow,e.cap));
198                 e.cap-=d;
199                 G[e.to][e.rev].cap+=d;
200                 flow+=d;
201                 if (f==flow) return f;
202             }
203         }
204 
205         gap[level[x]]--;
206         if (gap[level[x]]==0)
207             level[s]=n+1;
208         iter[x]=0;
209         gap[++level[x]]++;
210         return flow;
211     }
212 
213     int max_flow(int s, int t) {
214         int flow=0;
215         bfs(t);
216         memset(iter,0,sizeof(iter));
217         while (level[s]<=n)
218             flow+=dfs(s,s,t,INF);
219         return flow;
220     }
221 }
222 
223 int main() {
224     int s,t;
225     scanf("%d%d%d%d",&n,&m,&s,&t);
226     init();
227     printf("%d
",ISAP::max_flow(s,t));
228     return 0;
229 }
原文地址:https://www.cnblogs.com/tweetuzki/p/8413660.html