【算法】有上下界网络流-无源汇(循环流)
【题解】http://www.cnblogs.com/onioncyc/p/6496532.html
//未提交 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=1000,maxm=100000,inf=0x3f3f3f3f; struct edge{int from,v,flow;}e[maxm]; int S,T,TT,n,m,tot=1,first[maxn],cur[maxn],in[maxn],d[maxn],q[1010],lows[maxm]; void insert(int u,int v,int w) { tot++;e[tot].v=v;e[tot].flow=w;e[tot].from=first[u];first[u]=tot; tot++;e[tot].v=u;e[tot].flow=0;e[tot].from=first[v];first[v]=tot; } bool bfs() { memset(d,-1,sizeof(d)); int head=0,tail=1;q[0]=S;d[S]=0; while(head!=tail) { int x=q[head++];if(head>1000)head=0; for(int i=first[x];i;i=e[i].from) if(d[e[i].v]==-1&&e[i].flow) { d[e[i].v]=d[x]+1; q[tail++]=e[i].v; if(tail>1000)tail=0; } } return d[T]!=-1; } int dfs(int x,int a) { if(x==T||a==0)return a; int flow=0,f; for(int& i=cur[x];i;i=e[i].from) if(d[e[i].v]==d[x]+1&&(f=dfs(e[i].v,min(a,e[i].flow)))>0) { e[i].flow-=f; e[i^1].flow+=f; a-=f; flow+=f; if(a==0)break; } return flow; } int main() { scanf("%d",&TT); while(TT--) { memset(first,0,sizeof(first)); memset(in,0,sizeof(in)); tot=1; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d%d",&u,&v,&lows[i],&w); in[u]-=lows[i];in[v]+=lows[i]; insert(u,v,w-lows[i]); } S=0,T=n+1; for(int i=1;i<=n;i++) { if(in[i]>0)insert(S,i,in[i]); if(in[i]<0)insert(i,T,-in[i]); } while(bfs()) { for(int i=0;i<=n+1;i++)cur[i]=first[i]; dfs(S,inf); } bool ok=1; for(int i=first[S];i;i=e[i].from) if(e[i].flow)ok=0; if(ok) { printf("YES "); for(int i=2;i<=m*2;i+=2) printf("%d ",e[i^1].flow+lows[i>>1]); } else printf("NO "); } return 0; }