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;
}
View Code

 

posted @ 2018-09-11 14:02  shuai_hui  阅读(107)  评论(0编辑  收藏  举报