SGU 194. Reactor Cooling(无源汇有上下界的网络流)

时间:2021-01-22 08:11:07

时间限制:0.5s

空间限制:6M

题意:

显然就是求一个无源汇有上下界的网络流的可行流的问题

Solution:

没什么好说的,直接判定可行流,输出就好了

code

/*
无汇源有上下界的网络流
*/
#include <iostream>
#include <cstring>
#define ms(a,b) memset(a,b,sizeof a)
using namespace std;
const int MAXN = ; struct node {
int u, v, c, ne;
} edge[MAXN * MAXN << ];
int pHead[MAXN*MAXN], SS, ST, T, ncnt, ans;
int Gup[MAXN][MAXN], Glow[MAXN][MAXN], st[MAXN], ed[MAXN], cap[MAXN][MAXN], tflow; void addEdge (int u, int v, int c) {
edge[++ncnt].v = v, edge[ncnt].c = c, edge[ncnt].u = u;
edge[ncnt].ne = pHead[u], pHead[u] = ncnt;
edge[++ncnt].v = u, edge[ncnt].c = , edge[ncnt].u = v;
edge[ncnt].ne = pHead[v], pHead[v] = ncnt;
} int SAP (int pStart, int pEnd, int N) {
int numh[MAXN], h[MAXN], curEdge[MAXN], pre[MAXN];
int cur_flow, flow_ans = , u, neck, i, tmp;
ms (h, ); ms (numh, ); ms (pre, -);
for (i = ; i <= N; i++) curEdge[i] = pHead[i];
numh[] = N;
u = pStart;
while (h[pStart] <= N) {
if (u == pEnd) {
cur_flow = 1e9;
for (i = pStart; i != pEnd; i = edge[curEdge[i]].v)
if (cur_flow > edge[curEdge[i]].c) neck = i, cur_flow = edge[curEdge[i]].c;
for (i = pStart; i != pEnd; i = edge[curEdge[i]].v) {
tmp = curEdge[i];
edge[tmp].c -= cur_flow, edge[tmp ^ ].c += cur_flow;
}
flow_ans += cur_flow;
u = neck;
}
for ( i = curEdge[u]; i != ; i = edge[i].ne) {
if (edge[i].v > N) continue; //重要!!!
if (edge[i].c && h[u] == h[edge[i].v] + ) break;
}
if (i != ) {
curEdge[u] = i, pre[edge[i].v] = u;
u = edge[i].v;
}
else {
if ( == --numh[h[u]]) continue;
curEdge[u] = pHead[u];
for (tmp = N, i = pHead[u]; i != ; i = edge[i].ne) {
if (edge[i].v > N) continue; //重要!!!
if (edge[i].c) tmp = min (tmp, h[edge[i].v]);
}
h[u] = tmp + ;
++numh[h[u]];
if (u != pStart) u = pre[u];
}
}
return flow_ans;
}
int solve (int n) {
SS = n + , ST = n + ;
for (int i = ; i <= n; i++) {
if (ed[i]) addEdge (SS, i, ed[i]);
if (st[i]) addEdge (i, ST, st[i]);
}
int tem = SAP (SS, ST, ST);
if (tem != tflow) return ;
else
return ;
}
int n, m;
int main() {
ios::sync_with_stdio ();
ncnt = ;
cin >> n >> m;
for (int i = , u, v, x, y; i <= m; i++) {
cin >> u >> v >> x >> y;
Gup[u][v] = y, Glow[u][v] = x;
st[u] += x, ed[v] += x;
tflow += x;
addEdge (u, v, y - x);
}
if (solve (n) ) {
cout << "YES\n";
for (int i = , x, y; i <= m * ; i += ) {
x = edge[i].u, y = edge[i].v;
cout << Gup[x][y]-edge[i].c << '\n';
}
}
else
cout << "NO\n";
return ;
}