ZOJ2314 Reactor Cooling
来源:互联网 发布:安能快递有淘宝店用吗 编辑:程序博客网 时间:2024/06/05 17:41
一.题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314
二,题目大意:给一个无汇源点,流量有上下界限的图,求出是否有可行流,如果有,输出每条管子上的最大流。
三.思路:首先判断有无可行流,由于流量有上下界,于是,自然而然想到了每条弧用上界减去下界,但是这样违反了流量守恒(流入一个节点的流等于流出的)。
比如说:(u,v)上下界为(1,3), (v, q)上下界为(3,4)一条边减去2,另一条边减去了1,减去的流量不相等,相当于1的流量积累在v。于是我们可以想到建立源点、汇点来导流。
具体建图如下:
1.记录每个点的D = (每条进入它的弧的下界) 减去 (由它出发的弧的下界)。如果大于0,得到的就是积累在本节点的流量,于是建立一个汇点,把流导给它。容量为D。如果小于0,得到的就是本节点所需要进入的流量,建立一个源点s,跟它相连,容量为-D。
2.当然原来容量网络的每条弧保持一样,容量变为上界 减去 下界。
对于构造出来的图我们叫它伴随网络,(当然它的每条弧下界都为0)只有伴随网络的最大流使得从源点S出发,每条弧都满了(此时连到T的弧也一定会满),原来网络才有可行流。而本题还要求原容量网络中每条弧的可行流的流量,其实它只等于伴随网络中所对应的弧的流量加上每条弧流量的下界。而对于邻接表建图的话,伴随网络中所对应的弧的流量,就是第2*i条边的反向弧最后的流量。也就是2*i^1。
四.代码:
#include <iostream>#include <cstdio>#include <queue>#include <cstring>#include <cstdlib>using namespace std;const int INF = 0x3f3f3f3f, MAX_N = 209;class Dinic{public: struct Edge { int v, w, next; }; int cnt, head[MAX_N], dist[MAX_N], s, t; Edge edges[MAX_N*MAX_N]; void init(int is, int it) { cnt = 0; s = is, t = it; memset(head, -1, sizeof(head)); } void addEdge(int u, int v, int weight) { edges[cnt] = (Edge){v, weight, head[u]}; head[u] = cnt++; edges[cnt] = (Edge){u, 0, head[v]}; head[v] = cnt++; } bool BFS() { int i, cur; queue <int> que; que.push(s); memset(dist, -1, sizeof(dist)); dist[s] = 0; while(!que.empty()){ cur = que.front(); que.pop(); for(i = head[cur]; i != -1; i = edges[i].next) if(-1 == dist[edges[i].v] && edges[i].w){ dist[edges[i].v] = dist[cur] + 1; que.push(edges[i].v); } } return dist[t] != -1; } int DFS(int start, int curFlow) { if(start == t) return curFlow; int i, minFlow = 0, v, temp; for(i = head[start]; i != -1; i = edges[i].next){ v = edges[i].v; if(dist[start] == dist[v] - 1 && edges[i].w > 0){ temp = DFS(v, min(edges[i].w, curFlow)); edges[i].w -= temp; edges[i^1].w += temp; curFlow -= temp; minFlow += temp; if(0 == curFlow) break; } } if(0 == minFlow) dist[start] = -2; return minFlow; } int maxFlow() { int res = 0; while(BFS()){ res += DFS(s, INF); } return res; }}G;int nodeNum, edgeNum, cnt[MAX_N];int main(){ //freopen("in.txt", "r", stdin); int sum, i, j, test, u, v, down[MAX_N*MAX_N], up, s, t; scanf("%d", &test); while(test--){ scanf("%d%d", &nodeNum, &edgeNum); s = nodeNum + 1, t = nodeNum + 2; G.init(s, t); memset(cnt, 0, sizeof(cnt)); for(i = 0; i < edgeNum; i++){ scanf("%d%d%d%d", &u, &v, &down[i], &up); cnt[u] += down[i], cnt[v] -= down[i]; G.addEdge(u, v, up - down[i]); } sum = 0; for(i = 1; i <= nodeNum; i++){ if(cnt[i] > 0){ G.addEdge(i, t, cnt[i]); sum += cnt[i]; } else if(cnt[i] < 0) G.addEdge(s, i, -cnt[i]); } if(sum == G.maxFlow()){ printf("YES\n"); for(i = 0; i < edgeNum; i++) printf("%d\n", down[i] + G.edges[(2*i)^1].w); printf("\n"); } else printf("NO\n\n"); } return 0;}
0 0
- ZOJ2314 Reactor Cooling
- zoj2314 Reactor Cooling --- 上下界可行流
- 【上下界网络流】ZOJ2314 Reactor Cooling
- 【zoj2314】Reactor Cooling 无源汇可行流)
- ZOJ2314 Reactor Cooling (有上下界的网络流)
- [ZOJ2314]/[SGU194] Reactor Cooling 无源汇有上下界网络流
- [ZOJ2314]Reactor Cooling(无源汇有上下界的可行流)
- ZOJ2314 Reactor Cooling(无源汇上下界可行流)
- 【无源汇上下界可行流】ZOJ2314[Reactor Cooling]题解
- zoj2314 Reactor Cooling (无源汇的有上下界的最大流)
- SGU 194. Reactor Cooling
- zoj 2314 Reactor Cooling
- zoj 2314 Reactor Cooling
- sgu 194 Reactor Cooling
- ZOJ 2314 Reactor Cooling
- zoj Reactor Cooling
- zoj 2314 Reactor Cooling
- ZOJ Reactor Cooling
- 101. Symmetric Tree
- windows下用cmake构建项目时找不到pthread.h头文件
- 进程控制
- C# 将字节流转换为图片的实例方法,需要的朋友可以参考一下
- 最大流算法
- ZOJ2314 Reactor Cooling
- git里submodule的使用
- Activity的生命周期
- 聚类(一)pyspark 实现特征的ID化
- 88. Merge Sorted Array
- 使用ASP.NET OleDb驱动程序 导入到处EXCEL
- antlr.collections.AST.getLine()I异常
- baidu、google 简搜索框嵌入网页代码
- 文件下载