增加源和汇,所有边按照上界-下界作为上界,无下界建图,然后所有点的流入和流出统计,点流入的与源连上容量为流入量的边,流出的连上汇就行,做一次最大流,如果所有连接源点的边都满流就是有解,否则无解,解即当前边的流量加上原来的下界
错误n次~ 坑爹啊 以后要小心 注意未知数组尽量开到最大 本以为n为200 开10000不会有问题 结果100000才过。。。。
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#include<memory.h>
using namespace std;
const int maxn=1007,
maxm=100007,
inf=1<<30;
vector<int> next[maxn];
int b[maxn][maxn],flow[maxn][maxn];
int x[maxm],y[maxm];
int out[maxn];
int d[maxn];
bool bfs(int s,int t)
{
memset(d,0,sizeof(d));
d[s]=1;
queue<int> q;
q.push(s);
int i,u,v;
while(!q.empty())
{
u=q.front();
q.pop();
for(i=0;i<next[u].size();i++)
{
v=next[u][i];
if(flow[u][v]>0 && d[v]==0)
{
d[v]=d[u]+1;
if(v == t)
{
return true;
}
q.push(v);
}
}
}
return false;
}
int dfs(int u,int t,int limit)
{
if(u == t)
{
return limit;
}
int i,v,cost=0;
for(i=0;i<next[u].size();i++)
{
v=next[u][i];
if(flow[u][v]>0 && d[v]==d[u]+1)
{
int tmp = dfs(v,t,min(limit-cost,flow[u][v]));
if(tmp>0)
{
flow[u][v] -= tmp;
flow[v][u] += tmp;
cost += tmp;
if(cost == limit)
{
break;
}
}
else
{
d[v] = -1;
}
}
}
return cost;
}
int Dinic(int s,int t)
{
int ret=0;
while(bfs(s,t))
{
ret += dfs(s,t,inf);
}
return ret;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,n,m,u,v,l,c,s,t;
scanf("%d%d",&n,&m);
s=0,t=n+1;
memset(out,0,sizeof(out));
memset(flow,0,sizeof(flow));
memset(b,0,sizeof(b));
for(i=0;i<=t;i++)
{
next[i].clear();
}
for(i=0;i<m;i++)
{
scanf("%d%d%d%d",&u,&v,&l,&c);
next[u].push_back(v);
next[v].push_back(u);
out[u] -= l;
out[v] += l;
flow[u][v]=c-l;
b[u][v]=l;
x[i]=u;
y[i]=v;
}
int sum=0;
for(i=1;i<=n;i++)
{
if(out[i]>0)
{
next[s].push_back(i);
next[i].push_back(s);
flow[s][i]=out[i];
sum += out[i];
}
else if(out[i]<0)
{
next[i].push_back(t);
next[t].push_back(i);
flow[i][t] = -out[i];
}
}
if(Dinic(s,t) == sum)
{
puts("YES");
for(i=0;i<m;i++)
{
u=x[i],v=y[i];
printf("%d\n",flow[v][u]+b[u][v]);
}
}
else
{
puts("NO");
}
puts("");
}
return 0;
}