首页 > 代码库 > 有上下界网络流
有上下界网络流
sgu194:
//无源汇上下界网络流,求最大流。
/*
每条边add(u,v,up[i]-dn[i])
每个点out[i]=∑dn[i,v];in[i]=∑dn[v,i];
每个点in[i]-out[i]>0 add(s,i, in[i]-out[i]),否则add(i,t,out[i]-in[i]);
判断与st相连的边是否满流即可。
*/
#include<cstdio>#include<cstring>#include<cctype>#include<algorithm>using namespace std;#define rep(i,s,t) for(int i=s;i<=t;i++)#define dwn(i,s,t) for(int i=s;i>=t;i--)#define clr(x,c) memset(x,c,sizeof(x))#define qwq(x) for(edge *o=head[x];o;o=o->next)int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-‘0‘,c=getchar(); return x;}const int nmax=205;const int maxn=8e4+5;const int inf=0x7f7f7f7f;struct edge{ int to,cap;edge *next,*rev;};edge es[maxn],*pt=es,*head[nmax];void add(int u,int v,int d){ pt->to=v;pt->cap=d;pt->next=head[u];head[u]=pt++; pt->to=u;pt->cap=0;pt->next=head[v];head[v]=pt++; head[u]->rev=head[v];head[v]->rev=head[u];}edge *cur[nmax],*p[nmax];int cnt[nmax],h[nmax];int maxflow(int s,int t,int n){ cnt[0]=n;int flow=0,a=inf,x=s;edge *e; while(h[s]<n){ for(e=cur[x];e;e=e->next) if(e->cap>0&&h[x]==h[e->to]+1) break; if(e){ a=min(a,e->cap);cur[x]=p[e->to]=e;x=e->to; if(x==t){ while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to; flow+=a,a=inf; } }else{ if(!--cnt[h[x]]) break; h[x]=n; for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) cur[x]=e,h[x]=h[e->to]+1; cnt[h[x]]++; if(x!=s) x=p[x]->rev->to; } } return flow;}int out[nmax],in[nmax],dn[maxn];bool work(int s,int t,int n,int m){ maxflow(s,t,n); qwq(s) if(o->cap) return 0; qwq(t) if(o->cap!=out[o->to]-in[o->to]) return 0; puts("YES"); pt=es+1;rep(i,1,m) printf("%d\n",dn[i]+pt->cap),pt+=2; return 1;}int main(){ int n=read(),m=read(),u,v,d,tp; rep(i,1,m){ u=read(),v=read(),dn[i]=read();tp=read(); add(u,v,tp-dn[i]);in[v]+=dn[i];out[u]+=dn[i]; } rep(i,1,n){ if(in[i]-out[i]>0) add(0,i,in[i]-out[i]); else add(i,n+1,out[i]-in[i]); } if(!work(0,n+1,n+2,m)) puts("NO"); return 0;}
有上下界网络流
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。