sgu194 Reactor Cooling【无源汇有上下界可行流】
这是模板题了吧,先建立附加源汇,然后保留每个点的in-out,如果这个值是正的,那么就从附加源先这个点连一个边权为in-out的边,否则从这个点向附加汇连一条相反数的边,剩下题目中的边就用上界-下界连就好了。
1 #include <bits/stdc++.h> 2 #define rep(i, a, b) for (int i = a; i <= b; i++) 3 #define drep(i, a, b) for (int i = a; i >= b; i--) 4 #define REP(i, a, b) for (int i = a; i < b; i++) 5 #define mp make_pair 6 #define pb push_back 7 #define clr(x) memset(x, 0, sizeof(x)) 8 #define xx first 9 #define yy second 10 using namespace std; 11 typedef long long i64; 12 typedef pair<int, int> pii; 13 const int inf = ~0U >> 1; 14 const i64 INF = ~0ULL >> 1; 15 //*********************************** 16 17 const int maxn = 205, maxm = 40205; 18 19 struct Ed { 20 int u, v, nx, c; Ed() {} 21 Ed(int _u, int _v, int _nx, int _c) : 22 u(_u), v(_v), nx(_nx), c(_c) {} 23 } E[maxm << 1]; 24 int G[maxn], edtot = 1; 25 void addedge(int u, int v, int c) { 26 E[++edtot] = Ed(u, v, G[u], c); 27 G[u] = edtot; 28 E[++edtot] = Ed(v, u, G[v], 0); 29 G[v] = edtot; 30 } 31 32 int level[maxn], s, t; 33 bool bfs() { 34 static int que[maxn]; int qh(0), qt(0); 35 clr(level); 36 level[que[++qt] = s] = 1; 37 while (qh != qt) { 38 int x = que[++qh]; if (qh == maxn - 1) qh = 0; 39 for (int i = G[x]; i; i = E[i].nx) if (E[i].c && !level[E[i].v]) { 40 level[que[++qt] = E[i].v] = level[x] + 1; 41 if (qt == maxn - 1) qt = 0; 42 } 43 } 44 return !!level[t]; 45 } 46 int dfs(int u, int rm) { 47 if (u == t) return rm; 48 int rm1 = rm; 49 for (int i = G[u]; i; i = E[i].nx) { 50 if (E[i].c && level[E[i].v] == level[u] + 1) { 51 int flow = dfs(E[i].v, min(E[i].c, rm)); 52 E[i].c -= flow, E[i ^ 1].c += flow; 53 if ((rm -= flow) == 0) break; 54 } 55 } 56 if (rm1 == rm) level[u] = 0; 57 return rm1 - rm; 58 } 59 60 int l[maxm], in[maxn], out[maxn]; 61 int cnt; 62 int main() { 63 clr(G), edtot = 1, clr(in), clr(out); 64 int n, m; 65 scanf("%d%d", &n, &m); 66 s = n + 1, t = n + 2; 67 rep(i, 1, m) { 68 int x, y, a, b; scanf("%d%d%d%d", &x, &y, &a, &b); l[i] = a; 69 addedge(x, y, b - a); 70 in[y] += a, out[x] += a; 71 } 72 int sum(0); 73 rep(i, 1, n) { 74 if (in[i] > out[i]) addedge(s, i, in[i] - out[i]), sum += in[i] - out[i]; 75 else addedge(i, t, out[i] - in[i]); 76 } 77 int ans(0); 78 while (bfs()) ans += dfs(s, 0x3f3f3f3f); 79 if (ans != sum) { puts("NO"); return 0; } 80 puts("YES"); 81 for (int i = 1; i <= m; i++) printf("%d\n", E[(i << 1) ^ 1].c + l[i]); 82 return 0; 83 }