最大流 最小费用流模板

Posted hjmmm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大流 最小费用流模板相关的知识,希望对你有一定的参考价值。

 

技术分享图片
 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
", max_flow, min_cost);
84     return 0;
85 }
最小费用最大流EK

 

以上是关于最大流 最小费用流模板的主要内容,如果未能解决你的问题,请参考以下文章

最小费用最大流模板

最小费用最大流(luogu P3381 模板最小费用最大流)

模板最小费用最大流

最小费用流模板

最小费用最大流基础模板(洛谷3381)

最大流 && 最小费用最大流模板