SGU192 有上下界的网络流
无源汇有上下界可行流问题。
设\(in_i\)表示至少流到i的流量,\(out_i\)表示至少从i流出的流量。
对于每一条从u到v,流量上界为r,下界为l的边,容量存r-l,然后\(in_v = in_v + l\),\(out_u = out_u + l\)。
建超级源点s,超级汇点t,对于每个满足\(in_i > out_i\)的i,从s向i连容量为\(in_i-out_i\)的边,对于每个满足\(out_i>in_i\)的i,从i向t连容量为\(out_i-in_i\)的边,
接着从s向t跑最大流。
如果流量\(\not=\)从s连出来的边容量总和,则不行。
否则:每条边的流量为流量下界+新图中该边的流量。
/*
Author: CNYALI_LK
LANG: C++
PROG: sgu194.cpp
*/
#include<bits/stdc++.h>
#define up(a,b,c) for (int a(b),end##a(c);a<=end##a;++a)
#define down(a,c,b) for (int a(b),end##a(c);a>=end##a;--a)
#define uup(a,c,b) for (int a(b),end##a(c);a<=end##a;++a)
#define udown(a,b,c) for (int a(b),end##a(c);a>=end##a;--a)
#define endl '\n'
#define debug(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
const double eps=1e-8;
const double PI=acos(-1.0);
typedef long long ll;
struct inout{
//io优化省略
};
inout io;
template<class T>void chkmin(T &a,T b){a=a<b?a:b;}
template<class T>void chkmax(T &a,T b){a=a>b?a:b;}
int to[53333],lst[53333],w[53333],beg[233],e,s,t;
#define rev(x) (((x-1)^1)+1)
int out[233],in[233],sf[53333];
void add(int u,int v,int wea){
to[++e]=v;
lst[e]=beg[u];
w[e]=wea;
beg[u]=e;
}
int dis[233],q[233],cur[233],n;
int bfs(){
up(i,1,n)dis[i]=0,cur[i]=beg[i];
dis[s]=1;
int l,r,u,v;
l=r=1;
q[l]=s;
while(l<=r){
u=q[l];
for(int i=beg[u];i;i=lst[i])if(!dis[to[i]]&&w[i]){
dis[to[i]]=dis[u]+1;
q[++r]=to[i];
}
++l;
}
return dis[t];
}
int dfs(int x,int flw){
int f,i;
if(x==t){
return flw;
}
for(;cur[x];cur[x]=lst[cur[x]]){
i=cur[x];
if(w[i]&&dis[to[i]]==dis[x]+1){
if(f=dfs(to[i],min(flw,w[i]))){
w[i]-=f;
w[rev(i)]+=f;
return f;
}
}
}
return 0;
}
int main(){
#ifdef cnyali_lk
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
io.init();
int m,u,v,ww,l,r;
io>>n>>m;
s=n+1;
t=n+2;
up(i,1,m){
io>>u>>v>>l>>r;
out[u]+=l;
in[v]+=l;
ww=r-l;
add(u,v,ww);
add(v,u,0);
sf[i]=l;
}
int tot=0;
up(i,1,n)if(in[i]>out[i]){add(n+1,i,in[i]-out[i]);add(i,n+1,0);tot+=in[i]-out[i];}else if(in[i]<out[i]){add(i,n+2,out[i]-in[i]);add(n+2,i,0);}
n+=2;
int f,sum=0;
while(bfs()){
while(f=dfs(s,0x3f3f3f3f)){sum+=f;}
}
if(sum!=tot)io<<"NO\n";
else{
io<<"YES\n";
up(i,1,m){
io<<w[i*2]+sf[i]<<endl;
}
}
io.out();
return 0;
}