模板汇总——网络流
分类:
IT文章
•
2024-07-02 21:58:13
1. 最大流
const int N = 200;
const int M = N*N;
int head[N], deep[N], cur[N];
int w[M], to[M], nx[M];
int tot;
void add(int u, int v, int val){
w[tot] = val; to[tot] = v;
nx[tot] = head[u]; head[u] = tot++;
w[tot] = 0; to[tot] = u;
nx[tot] = head[v]; head[v] = tot++;
}
int bfs(int s, int t){
queue<int> q;
memset(deep, 0, sizeof(deep));
q.push(s);
deep[s] = 1;
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = head[u]; ~i; i = nx[i]){
if(w[i] > 0 && deep[to[i]] == 0){
deep[to[i]] = deep[u] + 1;
q.push(to[i]);
}
}
}
return deep[t] > 0;
}
int Dfs(int u, int t, int flow){
if(u == t) return flow;
for(int &i = cur[u]; ~i; i = nx[i]){
if(deep[u]+1 == deep[to[i]] && w[i] > 0){
int di = Dfs(to[i], t, min(w[i], flow));
if(di > 0){
w[i] -= di, w[i^1] += di;
return di;
}
}
}
return 0;
}
int Dinic(int s, int t){
int ans = 0, tmp;
while(bfs(s, t)){
for(int i = 0; i <= t; i++) cur[i] = head[i];
while(tmp = Dfs(s, t, inf)) ans += tmp;
}
return ans;
}
void init(){
memset(head, -1, sizeof(head));
tot = 0;
}
View Code
2. 二分图最优匹配
1 const int N = 210;
2 int val[N][N];
3 LL lx[N], ly[N], slack[N];
4 int linky[N];
5 LL pre[N];
6 bool vis[N], visx[N],visy[N];
7 void bfs(int k){
8 LL px, py = 0,yy = 0, d;
9 memset(pre, 0, sizeof(LL) * (n+2));
10 memset(slack, inf, sizeof(LL) * (n+2));
11 linky[py]=k;
12 do{
13 px = linky[py],d = INF, vis[py] = 1;
14 for(int i = 1; i <= n; i++)
15 if(!vis[i]){
16 if(slack[i] > lx[px] + ly[i] - val[px][i])
17 slack[i] = lx[px] + ly[i] -val[px][i], pre[i]=py;
18 if(slack[i]<d) d=slack[i],yy=i;
19 }
20 for(int i = 0; i <= n; i++)
21 if(vis[i]) lx[linky[i]] -= d, ly[i] += d;
22 else slack[i] -= d;
23 py = yy;
24 }while(linky[py]);
25 while(py) linky[py] = linky[pre[py]] , py=pre[py];
26 }
27 void KM(){
28 memset(lx, 0, sizeof(int)*(n+2));
29 memset(ly, 0, sizeof(int)*(n+2));
30 memset(linky, 0, sizeof(int)*(n+2));
31 for(int i = 1; i <= n; i++)
32 memset(vis, 0, sizeof(bool)*(n+2)), bfs(i);
33 }
34 void input(){
35 for(int i = 1; i <= n; i++){
36 for(int j = 1; j <= n; j++)
37 scanf("%d", &val[i][j]);
38 }
39 int main(){
40 input();
41 KM();
42 LL ans = 0;
43 for(int i = 1; i <= n; ++i)
44 ans += lx[i] + ly[i];
45 printf("%lld
", ans);
46 return 0;
47 }
View Code
结果是 尽可能多匹配情况下的 最大值, 如果需要求最小值, 在input 的时候将值取反, 最后输出的答案的时候也要取反。
3.最小花费最大流
KM+spfa
const int N = 1000;
const int M = N * N;
int head[N], to[M], ct[M], w[M], nt[M];
int d[N], vis[N];
int pre[N], id[N];
int tot;
void add(int u, int v, int flow, int cost){
to[tot] = v; ct[tot] = cost;
w[tot] = flow; nt[tot] = head[u]; head[u] = tot++;
to[tot] = u; ct[tot] = -cost;
w[tot] = 0; nt[tot] = head[v]; head[v] = tot++;
}
void init(){
memset(head, -1, sizeof(head));
tot = 0;
}
int spfa(int s, int t){
queue<int> q;
memset(d, inf, sizeof(d));
memset(vis, 0, sizeof(vis));
memset(pre, -1, sizeof(pre));
d[s] = 0;
q.push(s);
while(!q.empty()){
int u = q.front(); q.pop();
vis[u] = 0;
for(int i = head[u]; ~i; i = nt[i]){
if(w[i] > 0 && d[to[i]] > d[u] + ct[i]){
d[to[i]] = d[u] + ct[i];
pre[to[i]] = u;
id[to[i]] = i;
if(!vis[to[i]]){
vis[to[i]] = 1;
q.push(to[i]);
}
}
}
}
return d[t] < inf;
}
int MinCostFlow(int s, int t){
int Mi = inf;
int sum = 0;
int tt = 0;
while(spfa(s, t)){
Mi = inf;
for(int i = t; i != s; i = pre[i])
Mi = min(Mi, w[id[i]]);
for(int i = t; i != s; i = pre[i]){
w[id[i]] -= Mi;
w[id[i]^1] += Mi;
}
tt += Mi;
sum += d[t] * Mi;
}
return sum;
}
View Code
如果需要最大的花费, 建边的时候将值取反就了。
4.上下界网络流
无源汇有上下界限制的网络流
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
4 #define LL long long
5 #define ULL unsigned LL
6 #define fi first
7 #define se second
8 #define pb push_back
9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 #define _S(X) cout << x << ' ';
14 #define __S(x) cout << x << endl;
15 typedef pair<int,int> pll;
16 const int INF = 0x3f3f3f3f;
17 const LL mod = (int)1e9+7;
18 const int N = 20100;
19 const int _M = 500100;
20 int head[N];
21 int M[N];
22 int w[_M], to[_M], nx[_M], id[_M];
23 int B[_M];
24 int n, m, _u, _v, _w;
25 int tot, s, t, ss, tt;
26 int deep[N], cur[N];
27 void add(int u, int v, int val){
28 w[tot] = val;
29 to[tot] = v;
30 nx[tot] = head[u];
31 head[u] = tot++;
32 }
33
34 void init(){
35 memset(head, -1, sizeof(int)*(n+3));
36 memset(M, 0, sizeof(int)*(n+3));
37 tot = 0;
38 s = 1;
39 t = n;
40 ss = n + 1;
41 tt = n + 2;
42 }
43
44 int bfs(int s, int t){
45 queue<int> q;
46 memset(deep, 0, sizeof(int)*(n+3));
47 q.push(s);
48 deep[s] = 1;
49 while(!q.empty()){
50 int u = q.front();
51 q.pop();
52 for(int i = head[u]; ~i; i = nx[i]){
53 if(w[i] > 0 && deep[to[i]] == 0){
54 deep[to[i]] = deep[u] + 1;
55 q.push(to[i]);
56 }
57 }
58 }
59 if(deep[t] > 0) return 1;
60 return 0;
61 }
62 int Dfs(int u, int t, int flow){
63 if(u == t) return flow;
64 for(int &i = cur[u]; ~i; i = nx[i]){
65 if(deep[u]+1 == deep[to[i]] && w[i] > 0){
66 int di = Dfs(to[i], t, min(w[i], flow));
67 if(di > 0){
68 w[i] -= di, w[i^1] += di;
69 return di;
70 }
71 }
72 }
73 return 0;
74 }
75 int Dinic(int s, int t){
76 int ans = 0, tmp;
77 while(bfs(s, t)){
78 for(int i = 1; i <= n+2; i++) cur[i] = head[i];
79 while(tmp = Dfs(s, t, INF)) ans += tmp;
80 }
81 return ans;
82 }
83 int main(){
84 while(~scanf("%d%d", &n, &m)){
85 init();
86 int b, c;
87 for(int i = 1; i <= m; i++){
88 scanf("%d%d%d%d", &_u, &_v, &b, &c);
89 id[i] = tot; B[i] = b;
90 add(_u,_v,c-b); add(_v,_u,0);
91 M[_u] -= b; M[_v] += b;
92 }
93 int sum = 0;
94 for(int i = 1; i <= n; i++){
95 if(M[i] > 0) add(ss, i, M[i]), add(i, ss, 0), sum += M[i];
96 if(M[i] < 0) add(i, tt, -M[i]), add(tt, i, 0);
97 }
98 int ans = Dinic(ss, tt);
99 if(ans == sum){
100 puts("YES");
101 for(int i = 1; i <= m; i++)
102 printf("%d
",w[id[i]^1] + B[i]);
103 }
104 else puts("NO");
105 }
106 return 0;
107 }
View Code
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
4 #define LL long long
5 #define ULL unsigned LL
6 #define fi first
7 #define se second
8 #define pb push_back
9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 #define _S(X) cout << x << ' ';
14 #define __S(x) cout << x << endl;
15 typedef pair<int,int> pll;
16 const int INF = 0x3f3f3f3f;
17 const LL mod = (int)1e9+7;
18 const int N = 1000;
19 const int _M = 50010;
20 int head[N];
21 int M[N];
22 int w[_M], to[_M], nx[_M];
23 int n, m, _u, _v, _w;
24 int tot, s, t, ss, tt;
25 int deep[N], cur[N];
26 void add(int u, int v, int val){
27 w[tot] = val;
28 to[tot] = v;
29 nx[tot] = head[u];
30 head[u] = tot++;
31 }
32
33 void init(){
34 memset(head, -1, sizeof(int)*(n+3));
35 memset(M, 0, sizeof(int)*(n+3));
36 tot = 0;
37 ss = n + 1;
38 tt = n + 2;
39 }
40
41 int bfs(int s, int t){
42 queue<int> q;
43 memset(deep, 0, sizeof(int)*(n+3));
44 q.push(s);
45 deep[s] = 1;
46 while(!q.empty()){
47 int u = q.front();
48 q.pop();
49 for(int i = head[u]; ~i; i = nx[i]){
50 if(w[i] > 0 && deep[to[i]] == 0){
51 deep[to[i]] = deep[u] + 1;
52 q.push(to[i]);
53 }
54 }
55 }
56 if(deep[t] > 0) return 1;
57 return 0;
58 }
59 int Dfs(int u, int t, int flow){
60 if(u == t) return flow;
61 for(int &i = cur[u]; ~i; i = nx[i]){
62 if(deep[u]+1 == deep[to[i]] && w[i] > 0){
63 int di = Dfs(to[i], t, min(w[i], flow));
64 if(di > 0){
65 w[i] -= di, w[i^1] += di;
66 return di;
67 }
68 }
69 }
70 return 0;
71 }
72 int Dinic(int s, int t){
73 int ans = 0, tmp;
74 while(bfs(s,t)){
75 for(int i = 1; i <= n+2; i++) cur[i] = head[i];
76 while(tmp = Dfs(s, t, INF)) ans += tmp;
77 }
78 return ans;
79 }
80 int main(){
81 while(~scanf("%d%d", &n, &m)){
82 init();
83 scanf("%d%d", &s, &t);
84 int b, c;
85 for(int i = 1; i <= m; i++){
86 scanf("%d%d%d%d", &_u, &_v, &b, &c);
87 add(_u,_v,c-b); add(_v,_u,0);
88 M[_u] -= b; M[_v] += b;
89 }
90 int sum = 0;
91 for(int i = 1; i <= n; i++){
92 if(M[i] > 0) add(ss, i, M[i]), add(i, ss, 0), sum += M[i];
93 if(M[i] < 0) add(i, tt, -M[i]), add(tt, i, 0);
94 }
95 add(t,s,INF);
96 add(s,t,0);
97 int ans = Dinic(ss, tt);
98 if(ans == sum){
99 ans = w[--tot];
100 w[tot] = 0; w[--tot] = 0;
101 ans += Dinic(s, t);
102 printf("%d
", ans);
103 }
104 else puts("please go home to sleep");
105 }
106 return 0;
107 }