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 }
时间: 2024-08-06 22:57:36

ZOJ 2314 Reactor Cooling(无源汇上下界网络流)的相关文章

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

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 题意:给出N个点,M条边的有向图,每条边的有上下界规定,问是否存在一个可行流满足条件,如果满足输出YES并输出每条边的流量. 如果不满足输出NO. 根据周源的<一种简易的方法求解流量有上下界的网络中网络流问题> 无源汇上下界网络流的做法是: 设边u->v的下界是B(u,v),上界是C(u,v). 设M(i)为对于i结点的流入i的下界总和-流出i的下界总

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

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2314 题目大意: 给n个点,及m根pipe,每根pipe用来流躺液体的,单向的,每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体,里面流躺物质. 并且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题),同时最小不能低于Li. 解题思路: 转自:https://www.cnbl

hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )

题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到S的路径的费用和 + 重建这些T到S的双向路径的费用和. 思路1: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center&quo

hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流判断 )

题意:有n个点和m条有向边构成的网络,每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏所有S到T的路径的费用和 > 毁坏所有T到S的路径的费用和 + 重建这些T到S的双向路径的费用和. 思路1: 然后这个无源汇带上下界网络流的可行流问题的求解方法见这里~~ 建图就是上面说的那样啦~最后判断有没有可行流就是求一下我们所构造的这个新的网络的最大流~然后判断一下这个最大流是否满流~(即判断最大流是否和附加源点的流出总量相等~~) cod

无源汇上下界网络流

题目描述 这是一道模板题. n n n 个点,m m m 条边,每条边 e e e 有一个流量下界 lower(e) \text{lower}(e) lower(e) 和流量上界 upper(e) \text{upper}(e) upper(e),求一种可行方案使得在所有点满足流量平衡条件的前提下,所有边满足流量限制. 输入格式 第一行两个正整数 n n n.m m m. 之后的 m m m 行,每行四个整数 s s s.t t t.lower \text{lower} lower.upper

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

Reactor Coolinghttp://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nuclear re

ZOJ--2314--Reactor Cooling【无源汇上下界可行流】

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 题意:某恐怖组织要建立一个核反应堆,他们需要设计一个冷却系统,n个点由m个管子连接,为使液体循环流动,每个节点的总流入量需要等于总流出量,现告诉你每根管子的最小流量及最大流量及它们连接的两点(有向),问是否存在可行流,如存在,输出每个管子的流量. 有上下界的网络流分为四种:无源汇的上下界可行流.有源汇的上下界可行流.有源汇的上下界最大流.有源汇的上下界最小流,这道

hdu 4940 Destroy Transportation system (无源汇上下界可行流)

Destroy Transportation system Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)http://acm.hdu.edu.cn/showproblem.php?pid=4940 Problem Description Tom is a commander, his task is destroying his enemy’s transportatio

zoj 2314 Reactor Cooling 网络流

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nuclear reactor to produce plutonium for the nuclear bomb they are planning to create. Be