Zoj 2314 Reactor Cooling(无源汇有上下界可行流)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314
题意:
给n个点,及m根pipe,每根pipe用来流躺液体的,单向的,每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体,里面流躺物质。
并且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题),同时最小不能低于Li。
模板:无源汇有上下界可行流
#include<stdio.h> #include<string.h> #include<iostream> #include<queue> using namespace std; const int maxn=70005; int sp,tp,cnt=0,head[205],nxt[maxn],to[maxn],cap[maxn],dis[1005],low[maxn],def[205],m,n; inline int read(){ int ans=0; char last=' ',ch=getchar(); while(ch<'0' || ch>'9')last=ch,ch=getchar(); while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar(); if(last=='-')ans=-ans; return ans; } inline void add(int u,int v,int p){ nxt[cnt]=head[u],to[cnt]=v,cap[cnt]=p,head[u]=cnt++; nxt[cnt]=head[v],to[cnt]=u,cap[cnt]=0,head[v]=cnt++; } inline bool bfs(){ int u,e,v; queue<int> que; memset(dis,-1,sizeof(dis)); que.push(sp),dis[sp]=0; while(!que.empty()){ u=que.front(),que.pop(); for(int e=head[u];~e;e=nxt[e]){ if(cap[e]>0&&dis[v=to[e]]==-1){ dis[v]=dis[u]+1,que.push(v); if(v==tp) return true; } } } return false; } inline int dfs(const int &u,const int &flow){ if(u==tp) return flow; int res=0,v,flw; for(int e=head[u];~e;e=nxt[e]){ if(cap[e]>0&&dis[u]<dis[v=to[e]]){ flw=dfs(v,min(cap[e],flow-res)); if(flw==0) dis[v]=-1; cap[e]-=flw,cap[e^1]+=flw; res+=flw; if(res==flow) break; } } return res; } inline int dinic(int sp,int tp){ int ans=0; while(bfs()) { ans+=dfs(sp,1<<30); } return ans; } int main(){ int t; t=read(); while(t--) { cnt=0; memset(def,0,sizeof(def)); memset(head,-1,sizeof(head)); n=read(),m=read(); int s,t,up,down,sum=0; for(int i=1;i<=m;i++){ s=read(),t=read(),down=read(),up=read(); add(s,t,up-down); low[i]=down,def[s]+=down,def[t]-=down; } sp=n+1,tp=n+2; for(int i=1;i<=n;i++){ if(def[i]>0) sum+=def[i],add(i,tp,def[i]); if(def[i]<0) add(sp,i,-def[i]); } if(dinic(sp,tp)==sum){ cout<<"YES"<<endl; for(int i=1;i<=m;i++){ cout<<cap[((i-1)*2)^1]+low[i]<<endl; } } else cout<<"NO"<<endl; } return 0; }