我比较懒,可以参考《图论总结》。
#include <iostream>
#include <queue>
#include <stdio.h>
#include <memory.h>
using namespace std;
const int MAXN = 205;
const int MAXE = 45000;
const int INF = 0x3fffffff;
int d[MAXE],v[MAXE],u[MAXE],low[MAXE],up[MAXE],pre[MAXE],c[MAXN][MAXN],num[MAXE];
int s,t,n,m;
void ini_d(int s,int t) {
for(int i = 0; i < t+1; i++)
d[i] = t+1,num[i] = 0;
queue<int> q;
num[0] = 1;
d[t] = 0;
q.push(t);
int u;
while(!q.empty()) {
u = q.front();q.pop();
for(int i = 0; i < t + 1; i++) {
if(c[i][u] > 0 && d[i] >= t+1) {
d[i] = d[u] + 1;
num[d[i]]++;
q.push(i);
}
}
}
}
int findAlowArc(int i) {
int j;
for(j = 0; j < t + 1; j++) {
if(c[i][j] > 0 && d[i] == d[j] + 1) return j;
}
return -1;
}
int reLable(int i) {
int j;
int mm = INF;
for(j = 0; j < t + 1; j++) {
if(c[i][j] > 0) mm = min(mm,d[j] + 1);
}
return mm == INF?t+1:mm;
}
int maxFlow(int s,int t) {
ini_d(s,t);
int flow = 0,i = s,j;
int delta = INF;
memset(pre,-1,sizeof(pre));
while(d[s] < t+1) {
j = findAlowArc(i);
if(j >= 0) {
pre[j] = i;
i = j;
if(i == t) {
delta = INF;
for(i = t; i != s; i = pre[i])
delta = min(c[pre[i]][i],delta);
for(i = t; i != s; i = pre[i]) {
c[pre[i]][i] -= delta,c[i][pre[i]] += delta;
}
flow += delta;
}
}
else {
int x = reLable(i);
num[x]++;
num[d[i]]--;
if(num[d[i]] == 0) return flow;
d[i] = x;
if(i != s) i = pre[i];
}
}
return flow;
}
int main() {
int cas;
scanf("%d",&cas);
while(cas--) {
memset(c,0,sizeof(c));
memset(low,0,sizeof(low));
memset(up,0,sizeof(up));
int sum = 0;
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++) {
scanf("%d%d%d%d",&u[i],&v[i],&low[i],&up[i]);
c[u[i]][v[i]] += up[i] - low[i];
c[0][v[i]] += low[i];
c[u[i]][n+1] += low[i];
sum += low[i];
}
s = 0,t = n+1;
int ans = maxFlow(s,t);
if(ans != sum) {
puts("NO");
continue;
}
puts("YES");
for(int i = 1; i <= m; i++) {
printf("%d\n",c[v[i]][u[i]] + low[i]);
}
}
//system("pause");
return 0;
}