1. 程式人生 > >最大流 最小費用流模板

最大流 最小費用流模板

queue || bfs () const mes 最大流 amp -a

技術分享圖片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 using namespace std;
 6 const int INF = 0x3f3f3f3f;
 7 const int N = 10005;
 8 const int M = 100005;
 9 struct type{
10     int u, v, w, next;
11 }edge[M << 1];
12 int head[N], cnt;
13 int
dep[N], cur[N]; 14 int n, m, s, t, d; 15 void add(int x, int y, int z){ 16 edge[cnt].u = x; 17 edge[cnt].v = y; 18 edge[cnt].w = z; 19 edge[cnt].next = head[x]; 20 head[x] = cnt; 21 cnt++; 22 } 23 bool bfs(){ 24 int fro = 0; 25 queue<int> q; 26 q.push(s); 27 for
(int i = 1; i <= n; i++) dep[i] = 0; 28 dep[s] = 1;//important!!!!! 29 while(!q.empty()){ 30 fro = q.front(); q.pop(); 31 for(int i = head[fro]; i != -1; i = edge[i].next){ 32 int vv = edge[i].v; 33 if(!dep[vv] && edge[i].w > 0){ 34 dep[vv] = dep[fro] + 1
; 35 q.push(vv); 36 } 37 } 38 } 39 return dep[t] ? 1 : 0; 40 } 41 int dfs(int x, int rest){ 42 if(x == t || !rest) return rest; 43 for(int& i = cur[x]; i != -1; i = edge[i].next){//當前弧優化 44 int vv = edge[i].v, ww = edge[i].w; 45 if(dep[vv] != dep[x] + 1) continue; 46 d = dfs(vv, min(rest, ww)); 47 if(d > 0){ 48 edge[i].w -= d; 49 edge[i ^ 1].w += d; 50 return d; 51 } 52 } 53 return 0; 54 } 55 int dinic(){ 56 int ans = 0; 57 while(bfs()){ 58 for(int i = 1; i <= n; i++) cur[i] = head[i];//當前弧優化 59 if(d = dfs(s, INF)){ 60 ans += d; 61 } 62 } 63 return ans; 64 } 65 int main() { 66 int x, y, z; 67 scanf("%d%d%d%d", &n, &m, &s, &t); 68 for(int i = 1; i <= n; i++) head[i] = -1; 69 for(int i = 1; i <= m; i++){ 70 scanf("%d%d%d", &x, &y, &z); 71 add(x, y, z); 72 add(y, x, 0); 73 } 74 printf("%d", dinic()); 75 return 0; 76 }
最大流dinic

技術分享圖片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 using namespace std;
 6 const int INF = 0x3f3f3f3f;
 7 const int N = 5005;
 8 const int M = 50005;
 9 struct type{
10     int u, v, w, f, next;
11 }edge[M << 1];
12 struct type2{
13     int f, cur, incf;
14     bool vis;
15 }ser[N];
16 int head[N], cnt;
17 int n, m, s, t;
18 int max_flow, min_cost;
19 void add(int x, int y, int z, int zz){
20     edge[cnt].u = x;
21     edge[cnt].v = y;
22     edge[cnt].w = z;
23     edge[cnt].f = zz;
24     edge[cnt].next = head[x];
25     head[x] = cnt;
26     cnt++;
27 }
28 bool spfa(){
29     for(int i = 1; i <= n; i++){
30         ser[i].vis = 0;
31         ser[i].f = INF;
32     }
33     ser[s].f = 0;
34     ser[s].incf = INF;  
35     int fro;
36     queue<int> q;
37     q.push(s);
38     while(!q.empty()){
39         fro = q.front(); q.pop(); ser[fro].vis = 0;
40         for(int i = head[fro]; i != -1; i = edge[i].next){
41             int vv = edge[i].v, ww = edge[i].w, ff = edge[i].f;
42             if(ww > 0 && ser[fro].f + ff < ser[vv].f){
43                 ser[vv].f = ser[fro].f + ff;
44                 ser[vv].incf = min(ser[fro].incf, ww);
45                 ser[vv].cur = i;
46                 if(!ser[vv].vis){
47                     ser[vv].vis = 1;
48                     q.push(vv);
49                 }
50             }
51         }
52     }
53     return ser[t].f == INF ? 0 : 1;
54 }
55 void update(){
56     int i = t, j;
57     while(i != s){
58         j = ser[i].cur;
59         edge[j].w -= ser[t].incf;
60         edge[j ^ 1].w += ser[t].incf;
61         i = edge[j].u;
62     }
63     max_flow += ser[t].incf;
64     min_cost += ser[t].f * ser[t].incf;
65 }
66 void EK(){
67     while(spfa()){
68         update();
69     }
70 }
71 int main() {
72     //freopen("testdata.in", "r", stdin);
73     //freopen("testdata.out", "w", stdout);
74     int x, y, z, zz;
75     scanf("%d%d%d%d", &n, &m, &s, &t);
76     for(int i = 1; i <= n; i++) head[i] = -1;
77     for(int i = 1; i <= m; i++){
78         scanf("%d%d%d%d", &x, &y, &z, &zz);
79         add(x, y, z, zz);
80         add(y, x, 0, -zz);
81     }
82     EK();
83     printf("%d %d\n", max_flow, min_cost);
84     return 0;
85 }
最小費用最大流EK

最大流 最小費用流模板