题解:
有上限的网络流
基本模板
代码:
#include<bits/stdc++.h> using namespace std; const int N=100005; int ne[N],num,n,m,d[N],S,T,a,b,c,low[N],fi[N],zz[N],sl[N],dis[N],q[N]; void jb(int x,int y,int z) { ne[num]=fi[x]; fi[x]=num; zz[num]=y; sl[num++]=z; swap(x,y); z=0; ne[num]=fi[x]; fi[x]=num; zz[num]=y; sl[num++]=z; } int bfs() { memset(dis,0xff,sizeof dis); dis[1]=0; int l=0,r=1; q[1]=1; while (l<r) { int j=q[++l]; for (int i=fi[j];i!=-1;i=ne[i]) if (dis[zz[i]]<0&&sl[i]>0) { dis[zz[i]]=dis[j]+1; q[++r]=zz[i]; } } if (dis[n]>0)return 1; return 0; } int find(int x,int low) { int b=0; if (x==n)return low; for (int i=fi[x];i!=-1;i=ne[i]) if (sl[i]>0&&dis[zz[i]]==dis[x]+1&&(b=find(zz[i],min(low,sl[i])))) { sl[i]-=b; sl[i^1]+=b; return b; } return 0; } int main() { scanf("%d",&T); while (T--) { memset(fi,-1,sizeof fi); num=0; memset(d,0,sizeof d); scanf("%d%d",&n,&m); for (int i=0;i<m;i++) { scanf("%d%d%d%d",&a,&b,&low[i],&c); jb(a+1,b+1,c-low[i]); d[a]+=low[i];d[b]-=low[i]; } int tot=0; for (int i=1;i<=n;i++) { if (d[i]<0)jb(1,i+1,-d[i]); else jb(i+1,n+2,d[i]),tot+=d[i]; } n+=2; int t,ans=0; while (bfs()) while (t=find(1,1e9))ans+=t; if (tot!=ans)puts("NO"); else { puts("YES"); for (int i=0;i<m;i++) printf("%d ",sl[(i<<1)^1]+low[i]); } puts(""); } }