码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 2314 Reactor Cooling(无源汇有上下界可行流)

时间:2018-11-01 22:28:22      阅读:265      评论:0      收藏:0      [点我收藏+]

标签:link   设置   lin   printf   ini   欧拉   fas   不难   pll   

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2314

题目大意:

给n个点,及m根pipe,每根pipe用来流躺液体的,单向的,每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体,里面流躺物质。

并且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题),同时最小不能低于Li。

解题思路:

转自:https://www.cnblogs.com/WABoss/p/5371871.html

本质上就是求一个无源汇流量有上下界的容量网络的可行流,因为无源汇的容量网络上各个顶点都满足流量平衡条件,即所有点的∑流入流量=∑流出流量,可以看成里面的流是循环流动的,类似有向图欧拉回路。

而带上下界的网络可行流的求法,是根据网络流中一个流是可行流的充分必要条件——限制条件和平衡条件,去改造原网络,转化成不带下界的容量网络来求解的。数学模型那些证明之类的不难理解,见论文《一种简易的方法求解流量有上下界的网络中网络流问题》。

而改造的方式好像有两种挺流行的,我用的做法是:

  • 设d[u]为顶点u出边下界和-入边下界和,新建源点、汇点
  • 原网络的弧<u,v>容量设置成其上界-下界
  • 对于每一个顶点u,如果d[u]<0则源点向其连容量-d[u]的边,否则其向汇点连容量d[u]的边
  • 最后如果和源点相关的弧都满流则存在可行流,而各条边的流量+其在原网络的下界就是一个解

代码

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 #include<queue>
  7 #include<vector>
  8 #define LL long long
  9 #define pii pair<int,int>
 10 #define pll pair<long long,long long>
 11 #define rep(i,a,b) for(int i=a;i<=b;i++)
 12 #define per(i,a,b) for(int i=a;i>=b;i--)
 13 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
 14 #define bug cout<<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"<<endl;
 15 #define bugc(_) cout << (#_) << " = " << (_) << endl;
 16 using namespace std;
 17 const int N=2e2+5;
 18 const int M=4e4+5;
 19 const int INF=0x3f3f3f3f;
 20 
 21 struct node{
 22     int to,next,flow;
 23 }edge[M*2];
 24 
 25 int cnt,st,en;
 26 int head[N],dep[N],d[N],low[M];//d[u]为顶点u出边下界和-入边下界和,low[i]记录第i条边的下界 
 27 
 28 void init(){
 29     cnt=2;
 30     memset(head,0,sizeof(head));
 31     memset(d,0,sizeof(d));
 32 }
 33 
 34 void link(int u,int v,int flow){
 35     edge[cnt]=node{v,head[u],flow};
 36     head[u]=cnt++;
 37     edge[cnt]=node{u,head[v],0};
 38     head[v]=cnt++;
 39 }
 40 
 41 int bfs(){
 42     memset(dep,0,sizeof(dep));
 43     dep[st]=1;
 44     queue<int>q;
 45     q.push(st);
 46     while(!q.empty()){
 47         int u=q.front();
 48         q.pop();
 49         for(int i=head[u];i;i=edge[i].next){
 50             node t=edge[i];
 51             if(t.flow&&!dep[t.to]){
 52                 dep[t.to]=dep[u]+1;
 53                 q.push(t.to);
 54             }
 55         }
 56     }
 57     return dep[en];
 58 }
 59 
 60 int dfs(int u,int fl){
 61     if(en==u) return fl;
 62     int tmp=0;
 63     for(int i=head[u];i&&fl;i=edge[i].next){
 64         node &t=edge[i];
 65         if(t.flow&&dep[t.to]==dep[u]+1){
 66             int x=dfs(t.to,min(t.flow,fl));
 67             if(x>0){
 68                 tmp+=x;
 69                 fl-=x;
 70                 t.flow-=x;
 71                 edge[i^1].flow+=x;
 72             }
 73         }
 74     }
 75     if(!tmp) dep[u]=-2;
 76     return tmp;
 77 }
 78 
 79 int dinic(){
 80     int ans=0;
 81     while(bfs()){
 82         while(int d=dfs(st,INF))
 83             ans+=d;
 84     }
 85     return ans;
 86 }
 87 
 88 int main(){
 89     int T;
 90     scanf("%d",&T);
 91     while(T--){
 92         int n,m;
 93         scanf("%d%d",&n,&m);
 94         init();
 95         st=0,en=n+1;
 96         for(int i=1;i<=m;i++){
 97             int u,v,c;
 98             scanf("%d%d%d%d",&u,&v,&low[i],&c);
 99             link(u,v,c-low[i]);
100             d[u]+=low[i];
101             d[v]-=low[i];
102         }
103         int sum=0;
104         for(int i=1;i<=n;i++){
105             if(d[i]<0) link(st,i,-d[i]);
106             else{
107                 sum+=d[i];
108                 link(i,en,d[i]);
109             }
110         }
111         if(sum!=dinic()) puts("NO");
112         else{
113             puts("YES");
114             for(int i=2;i<=2*m;i+=2){
115                 printf("%d\n",edge[i^1].flow+low[i>>1]);
116             }
117         }
118         puts("");
119     }
120     return 0;
121 }

 

ZOJ 2314 Reactor Cooling(无源汇有上下界可行流)

标签:link   设置   lin   printf   ini   欧拉   fas   不难   pll   

原文地址:https://www.cnblogs.com/fu3638/p/9892416.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!