http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314
大牛就是大牛 人家能想到咱就是想不到呀
根据所给流量下限(下限必流)
记录每个点的入度(in) 和出度(out) 然后用(上限-下限)进行建图 (这是还可以增加的流)
然后虚拟起点和汇点 根据每个点的 in 和 out
如果 in > out 说明此点需要流出(in - out ) 然后从起点连一条边 流为( in - out ) 等于给此点一个流出的机会
如果 in < out 说明此点需要流入 (out - in ) 然后向终点连一条边 流为 ( out - in ) 等于给此点一个流入的机会
然后求最大流 看是否最大流为满流(既等于初始化时从起点需要流出的量 且等于初始化时需要向汇点流入的量)
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<map> #include<set> #include<vector> #include<stack> #include<queue> //#pragma comment(linker, "/STACK:1024000000,1024000000") #define ll long long using namespace std; const int INF=0x3f3f3f3f; const int MOD=100000007; const int N=205; const int M=100005; int head[N],I; struct node { int j,next; int k; int flow; }edge[M]; struct node1 { int l,r,low,high; }p[M]; int in[N],out[N]; int L[N]; int st,nd; void add(int i,int j,int flow,int k) { edge[I].j=j; edge[I].k=k; edge[I].flow=flow; edge[I].next=head[i]; head[i]=I++; } bool bfs(int x1,int x2) { memset(L,-1,sizeof(L)); queue<int>qt; qt.push(x1); L[x1]=0; while(!qt.empty()) { int x=qt.front(); qt.pop(); for(int t=head[x];t!=-1;t=edge[t].next) { int j=edge[t].j; if(edge[t^1].flow>0&&L[j]==-1) { L[j]=L[x]+1; qt.push(j); } } } if(L[x2]==-1) return false; return true; } int dfs(int x,int sum) { if(x==nd) return sum; int tmp=sum; for(int t=head[x];t!=-1;t=edge[t].next) { int j=edge[t].j; if(edge[t].flow>0&&L[x]==L[j]+1) { int w=dfs(j,min(tmp,edge[t].flow)); edge[t].flow-=w;int k=edge[t].k;if(k!=-1)p[k].low+=w; edge[t^1].flow+=w;k=edge[t^1].k;if(k!=-1)p[k].low-=w; tmp-=w; if(tmp==0) break; } } return (sum-tmp); } void init(int n,int m,int st,int nd,int &S,int &E) { memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); for(int i=0;i<m;++i) { cin>>p[i].l>>p[i].r>>p[i].low>>p[i].high; out[p[i].l]+=p[i].low; in[p[i].r]+=p[i].low; add(p[i].l,p[i].r,p[i].high-p[i].low,i); add(p[i].r,p[i].l,0,-1); } for(int i=1;i<=n;++i) { if(in[i]>out[i]) { add(st,i,in[i]-out[i],-1); add(i,st,0,-1); S+=(in[i]-out[i]); } if(in[i]<out[i]) { add(i,nd,out[i]-in[i],-1); add(nd,i,0,-1); E+=(out[i]-in[i]); } } } int main() { //freopen("data.in","r",stdin); int T; cin>>T; while(T--) { int n,m; while(cin>>n>>m)//cout<<n<<m<<endl; { memset(head,-1,sizeof(head)); I=0; st=0; nd=n+1; int S=0,E=0; init(n,m,st,nd,S,E);//cout<<S<<" "<<E<<endl; int ans=0; while(bfs(nd,st)) { int k; while((k=dfs(st,INF))) ans+=k; } //cout<<ans<<" "<<S<<" "<<E<<endl; if(S==ans&&E==ans) { cout<<"YES"<<endl; for(int i=0;i<m;++i) cout<<p[i].low<<endl; } else { cout<<"NO"<<endl; } } } return 0; }