ZOJ 2314 Reactor Cooling(无源汇上下界网络流)

Posted 谦谦君子,陌上其华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ 2314 Reactor Cooling(无源汇上下界网络流)相关的知识,希望对你有一定的参考价值。

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2314

题意:

给出每条边流量的上下界,问是否存在可行流,如果存在则输出。

 

思路:
先定义D(u)为顶点u发出的所有弧的流量下界与进入顶点u的所有弧的流量下界和之差(out【u】-in【u】)。

对于无源汇的网络流来说:

(1)新增两个顶点S(附加源点)和T(附加汇点)。

(2)对原网络中每个顶点u,计算出D(u),如果D(u)>0,则增加一条新弧<u,T>,这条弧的容量为D(u);如果D(u)<0,则增加一条新弧<S,u>,这条弧的容量为-D(u);如果D(u)=0,则不增加弧。

(3)原网络中的每条弧的容量更改为c-b(上界-下界)。

跑一遍最大流,如果满流,则存在可行流,每条边的实际流量=每条边的流量+该边流量下界。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<sstream>
  6 #include<vector>
  7 #include<stack>
  8 #include<queue>
  9 #include<cmath>
 10 #include<map>
 11 #include<set>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef pair<int,int> pll;
 15 const int INF = 0x3f3f3f3f;
 16 const int maxn = 50000 + 5;
 17 
 18 int n, m;
 19 
 20 int in[maxn];
 21 int out[maxn];
 22 int b[maxn];
 23 
 24 struct Edge
 25 {
 26     int from,to,cap,flow;
 27     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
 28 };
 29 
 30 struct Dinic
 31 {
 32     int n,m,s,t;
 33     vector<Edge> edges;
 34     vector<int> G[maxn];
 35     bool vis[maxn];
 36     int cur[maxn];
 37     int d[maxn];
 38 
 39     void init(int n)
 40     {
 41         this->n=n;
 42         for(int i=0;i<n;++i) G[i].clear();
 43         edges.clear();
 44     }
 45 
 46     void AddEdge(int from,int to,int cap)
 47     {
 48         edges.push_back( Edge(from,to,cap,0) );
 49         edges.push_back( Edge(to,from,0,0) );
 50         m=edges.size();
 51         G[from].push_back(m-2);
 52         G[to].push_back(m-1);
 53     }
 54 
 55     bool BFS()
 56     {
 57         queue<int> Q;
 58         memset(vis,0,sizeof(vis));
 59         vis[s]=true;
 60         d[s]=0;
 61         Q.push(s);
 62         while(!Q.empty())
 63         {
 64             int x=Q.front(); Q.pop();
 65             for(int i=0;i<G[x].size();++i)
 66             {
 67                 Edge& e=edges[G[x][i]];
 68                 if(!vis[e.to] && e.cap>e.flow)
 69                 {
 70                     vis[e.to]=true;
 71                     d[e.to]=d[x]+1;
 72                     Q.push(e.to);
 73                 }
 74             }
 75         }
 76         return vis[t];
 77     }
 78 
 79     int DFS(int x,int a)
 80     {
 81         if(x==t || a==0) return a;
 82         int flow=0, f;
 83         for(int &i=cur[x];i<G[x].size();++i)
 84         {
 85             Edge &e=edges[G[x][i]];
 86             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)
 87             {
 88                 e.flow +=f;
 89                 edges[G[x][i]^1].flow -=f;
 90                 flow +=f;
 91                 a -=f;
 92                 if(a==0) break;
 93             }
 94         }
 95         return flow;
 96     }
 97 
 98     int Maxflow(int s,int t)
 99     {
100         this->s=s; this->t=t;
101         int flow=0;
102         while(BFS())
103         {
104             memset(cur,0,sizeof(cur));
105             flow +=DFS(s,INF);
106         }
107         return flow;
108     }
109 
110     void print(int num)
111     {
112         for(int i=0;i<num;i++)
113         {
114             printf("%d\n",edges[2*i].flow+b[i]);
115         }
116     }
117 }DC;
118 
119 int main()
120 {
121     //freopen("in.txt","r",stdin);
122     int T;
123     scanf("%d",&T);
124     while(T--)
125     {
126         scanf("%d%d",&n, &m);
127         int src=0, dst=n+1;
128         DC.init(dst+1);
129 
130         memset(in,0,sizeof(in));
131         memset(out,0,sizeof(out));
132 
133         for(int i=0;i<m;i++)
134         {
135             int u, v, c;
136             scanf("%d%d%d%d",&u,&v,&b[i],&c);
137             DC.AddEdge(u,v,c-b[i]);
138             out[u]+=b[i];
139             in[v]+=b[i];
140         }
141 
142         int flow=0;
143         for(int i=1;i<=n;i++)
144         {
145             if(out[i]<in[i])
146             {
147                 DC.AddEdge(src,i,in[i]-out[i]);
148                 flow+=in[i]-out[i];
149             }
150             else
151             {
152                 DC.AddEdge(i,dst,out[i]-in[i]);
153             }
154         }
155 
156         if(DC.Maxflow(src,dst)!=flow)   {puts("NO");puts("");continue;}
157 
158         puts("YES");
159         DC.print(m);
160         puts("");
161     }
162     return 0;
163 }

 

以上是关于ZOJ 2314 Reactor Cooling(无源汇上下界网络流)的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ2314:Reactor Cooling——题解

ZOJ_2314_Reactor Cooling_有上下界可行流模板

Reactor Cooling ZOJ - 2314 上下界网络流

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

zoj 2314Reactor Cooling

ZOJ2314 Reactor Cooling