题意:看是否有无源汇上下界可行流,如果有输出流量
题解:对于每一条边u->v,上界high,下界low,来说,我们可以建立每条边流量为high-low,那么这样得到的流量可能会不守恒(流入量!=流出量),这时我们要想使得流量守恒,我们需要建立附加流,附加流 是在刚才的图上的改进流,对于每一个点如果有流入量(in)>流出量(out),那么对于多余的流入量,我们需要想办法新加一条边流量为in-out流入该点,反之如果in<out,那么需要建立一条边流量为out-in流出该点,我们此时可以建立一个超级源和超级汇,此时我们在附加流上跑一遍最大流,如果从超级源出发的所有流量等于最大流,也就是说能保证流量守恒,那么就是有可行流,每条边的可行流等于该边的轮流下界+附加流中的流过的流量(既附加流中反向边的流量)

#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-12; const int N=200+10,maxn=40000+10,inf=0x3f3f3f; struct edge{ int from,to,Next,c,low; }e[maxn<<2]; int cnt,head[N]; int dis[N],s,t; int out[N],in[N]; void add(int u,int v,int c,int low) { e[cnt].from=u; e[cnt].low=low; e[cnt].to=v; e[cnt].c=c; e[cnt].Next=head[u]; head[u]=cnt++; e[cnt].from=v; e[cnt].low=low; e[cnt].to=u; e[cnt].c=0; e[cnt].Next=head[v]; head[v]=cnt++; } bool bfs() { memset(dis,-1,sizeof dis); dis[s]=0; queue<int>q; q.push(s); while(!q.empty()) { int x=q.front(); q.pop(); for(int i=head[x];~i;i=e[i].Next) { int te=e[i].to; if(e[i].c>0&&dis[te]==-1) { dis[te]=dis[x]+1; q.push(te); } } } return dis[t]!=-1; } int dfs(int x,int mx) { if(x==t)return mx; int flow=0; for(int i=head[x];~i;i=e[i].Next) { int te=e[i].to,f; if(dis[te]==dis[x]+1&&e[i].c>0&&(f=dfs(te,min(mx-flow,e[i].c)))) { e[i].c-=f; e[i^1].c+=f; flow+=f; } } if(!flow)dis[x]=-2; return flow; } int maxflow() { int ans=0,f; while(bfs()) { while((f=dfs(s,inf)))ans+=f; } return ans; } void init() { cnt=0; memset(head,-1,sizeof head); memset(out,0,sizeof out); memset(in,0,sizeof in); } int main() { ios::sync_with_stdio(false); cin.tie(0); int T; cin>>T; while(T--) { int n,m; cin>>n>>m; init(); for(int i=0; i<m; i++) { int a,b,c,d; cin>>a>>b>>c>>d; out[a]+=c; in[b]+=c; add(a,b,d-c,c); } s=n+1,t=n+2; int sum=0; for(int i=1; i<=n; i++) { if(in[i]>out[i])sum+=in[i]-out[i],add(s,i,in[i]-out[i],0); else add(i,t,out[i]-in[i],0); } if(sum==maxflow()) { cout<<"YES"<<endl; for(int i=0;i<2*m;i+=2) cout<<e[i^1].c+e[i].low<<endl; } else cout<<"NO"<<endl; } return 0; } /******************** ********************/