給定一個無源無匯的網絡,邊的容量有上下界限制,試構造一個合理的流量。node
求無源匯上下界的可行流模板題。ios
①增長一個附加源和匯\(S,T\)。git
②把每一個節點的\(\sum b_{u,i}\)和\(\sum b_{i,v}\)求出來,\(b\)是指下界。網絡
③對於每一個節點,若\(\sum b_{u,i}-\sum b_{i,v}>0\),則添一條從\(S\)到\(i\),容量爲\(\sum b_{u,i}-\sum b_{i,v}\)的邊。spa
若\(\sum b_{u,i}-\sum b_{i,v}<0\),則添一條從\(i\)到\(T\),容量爲\(\sum b_{i,v}-\sum b_{u,i}\)的邊。code
④對於原網絡中的點,連一條容量爲 up-down 的邊。ip
⑤求從\(S\)到\(T\)的最大流,若全部與\(S\)相連的邊或與\(T\)相連的邊都滿載,則這是一個可行解,方案爲④中所連邊的剩餘流量+\(b\)。get
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<iomanip> #include<cstdlib> #define MAXN 0x7fffffff typedef long long LL; const int N=205*205; using namespace std; inline int Getint(){register int x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;} int n,m,S,T,num; struct node{int next,to,pair,flow;}g[N<<1]; int h[N],cnt; void AddEdge(int x,int y,int z){ g[++cnt].to=y,g[cnt].next=h[x],h[x]=cnt,g[cnt].flow=z,g[cnt].pair=cnt+1; g[++cnt].to=x,g[cnt].next=h[y],h[y]=cnt,g[cnt].flow=0,g[cnt].pair=cnt-1; } int GAP[N],dis[N]; void Init(){ static int q[N]; int l=0,r=1;q[++l]=T,++GAP[dis[T]=1]; while(l<=r){ int x=q[l++]; for(int i=h[x];i;i=g[i].next){ int to=g[i].to; if(!dis[to])++GAP[dis[to]=dis[x]+1],q[++r]=to; } } } int Dfs(int x,int Maxf){ if(x==T||!Maxf)return Maxf; int ret=0; for(int i=h[x];i;i=g[i].next){ int to=g[i].to; if(g[i].flow&&dis[x]==dis[to]+1){ int dlt=Dfs(to,min(g[i].flow,Maxf-ret)); g[i].flow-=dlt; g[g[i].pair].flow+=dlt; ret+=dlt; if(dis[S]==num+1||ret==Maxf)return ret; } } if(!(--GAP[dis[x]]))dis[S]=num+1; else GAP[++dis[x]]++; return ret; } int SAP(){ Init(); int ans=Dfs(S,MAXN); while(dis[S]<=num)ans+=Dfs(S,MAXN); return ans; } struct Edge{int x,y,b,c;}s[N]; int inb[N],otb[N]; int main(){ n=Getint(),m=Getint(),S=0,T=n+m+1,num=T+1; for(int i=1;i<=m;i++){ s[i].x=Getint(),s[i].y=Getint(),s[i].b=Getint(),s[i].c=Getint(); AddEdge(s[i].x,s[i].y,s[i].c-s[i].b); inb[s[i].y]+=s[i].b,otb[s[i].x]+=s[i].b; } for(int i=1;i<=n;i++) if(inb[i]>otb[i])AddEdge(S,i,inb[i]-otb[i]); else AddEdge(i,T,otb[i]-inb[i]); SAP(); bool flag=0; for(int i=h[S];i;i=g[i].next)flag|=(g[i].flow>0); cout<<((flag)?"NO":"YES"); return 0; }