POJ 3801 有上下界最小流
1: /**
2: POJ 3801 有上下界的最小流
3:
4: 1、对supersrc到supersink 求一次最大流,记为f1。(在有源汇的情况下,先使整个网络趋向必须边尽量满足的情况)
5: 2、添加一条边sink -> src,流量上限为INF,这条边记为p。(构造无源汇网络)
6: 3、对supersrc到supersink再次求最大流,记为f2,这里判断是否为可行流。(要判断可行,必须先构造无源汇网络流,因此要再次求最大流)
7:
8: 此网络流的最小流即为 sink -> src 的流量
9: */
10:
11: #include<iostream>
12: #include<cmath>
13: #include<memory>
14: #include <string.h>
15: #include <cstdio>
16: #include <vector>
17: using namespace std;
18:
19: #define V 150 // vertex
20: #define E (V*V) // edge
21: #define INF 0x3F3F3F3F // 1061109567
22:
23: int i,j,k;
24: #define REP(i,n) for((i)=0;(i)<(int)(n);(i)++)
25: #define snuke(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)
26:
27: struct MaxFlow
28: {
29: struct Edge
30: {
31: int v, w, next; //w for capicity
32: int lb,up;
33: } edge[E];
34:
35: int head[V]; // head[u]表示顶点u第一条邻接边的序号, 若head[u] = -1, u没有邻接边
36: int e; // the index of the edge
37: int src, sink;
38: int net[V]; // 流入此节点的流的下界和 - 流出此节点的流的下界和,对于带上下界的来进行使用
39:
40:
41: void addedge(int u, int v, int w, int lb = 0, int up = INF, int rw = 0)
42: {
43: edge[e].v = v;
44: edge[e].w= w;
45: edge[e].next = head[u];
46: edge[e].lb = lb, edge[e].up = up;
47: head[u] = e++;
48: // reverse edge v -> u
49: edge[e].v = u;
50: edge[e].w = rw;
51: edge[e].lb = lb, edge[e].up = up;
52: edge[e].next = head[v];
53: head[v] = e++;
54: }
55:
56: int ISAP(int VertexNum )
57: {
58: int u, v, max_flow, aug, min_lev;
59: int curedge[V], parent[V], level[V];
60: int count[V], augment[V];
61:
62: memset(level, 0, sizeof(level));
63: memset(count, 0, sizeof(count));
64: REP(i,VertexNum+1) curedge[i] = head[i];
65: max_flow = 0;
66: augment[src] = INF;
67: parent[src] = -1;
68: u = src;
69:
70: while (level[src] < VertexNum)
71: {
72: if (u == sink)
73: {
74: max_flow += augment[sink];
75: aug = augment[sink];
76: for (v = parent[sink]; v != -1; v = parent[v])
77: {
78: i = curedge[v];
79: edge[i].w -= aug;
80: edge[i^1].w += aug;
81: augment[edge[i].v] -= aug;
82: if (edge[i].w == 0) u = v;
83: }
84: }
85: for (i = curedge[u]; i != -1; i = edge[i].next)
86: {
87: v = edge[i].v;
88: if (edge[i].w > 0 && level[u] == (level[v]+1))
89: {
90: augment[v] = min(augment[u], edge[i].w);
91: curedge[u] = i;
92: parent[v] = u;
93: u = v;
94: break;
95: }
96: }
97: if (i == -1)
98: {
99: if (--count[level[u]] == 0) break;
100: curedge[u] = head[u];
101: min_lev = VertexNum;
102: for (i = head[u]; i != -1; i = edge[i].next)
103: if (edge[i].w > 0)
104: min_lev = min(level[edge[i].v], min_lev);
105: level[u] = min_lev + 1;
106: count[level[u]]++;
107: if (u != src ) u = parent[u];
108: }
109: }
110: return max_flow;
111: }
112: void solve()
113: {
114: int n, m;
115: while (scanf("%d %d", &n, &m) != EOF)
116: {
117: if (n+m == 0) break;
118: e = 0;
119: memset(head, -1, sizeof(head));
120: memset(net, 0, sizeof(net));
121:
122: int s = n+1, t = n+2;
123: src = n+3, sink = n+4;
124: char a[5], b[5];
125: int c;
126: while (m--)
127: {
128: scanf("%s %s %d", a, b, &c);
129: int u, v;
130: if (a[0] == '+') u = s;
131: else sscanf(a, "%d", &u); // 注意这里读取信息
132: if (b[0] == '-') v = t;
133: else sscanf(b, "%d", &v);
134: net[v] += c, net[u] -= c;
135: addedge(u,v,INF,c, INF);
136: }
137: vector<int> CE;
138: for(int i=1; i<=n+2; i++)
139: {
140: if(net[i] >=0)
141: {
142: CE.push_back(e);
143: addedge(src, i, net[i]);
144: }
145: else
146: {
147: CE.push_back(e);
148: addedge(i, sink, -net[i]);
149: }
150: }
151: int flow = 0;
152: flow = ISAP(n+4);
153: int p = e;
154: addedge(t, s, INF, 0, INF);
155: flow += ISAP(n+4);
156: bool flag = true;
157: for(int i= 0; i< CE.size(); i++)
158: {
159: if(edge[CE[i]].w !=0)
160: {
161: flag = false;
162: break;
163: }
164: }
165: if (!flag)
166: printf("impossible\n");
167: else
168: printf("%d\n", edge[p^1].w);
169: }
170: }
171: } sap;
172:
173: int main()
174: {
175: // freopen("1.txt","r",stdin);
176: sap.solve();
177: return 0;
178: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
POJ 3801 有上下界最小流的更多相关文章
- sgu 176 Flow construction(有源汇的上下界最小流)
[题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11025 [模型] 有源汇点的上下界最小流.即既满足上下界又满足 ...
- BZOJ_2502_清理雪道_有源汇上下界最小流
BZOJ_2502_清理雪道_有源汇上下界最小流 Description 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道), ...
- 【Loj117】有源汇上下界最小流(网络流)
[Loj117]有源汇上下界最小流(网络流) 题面 Loj 题解 还是模板题. #include<iostream> #include<cstdio> #include< ...
- SGU 176 Flow construction (有源有汇有上下界最小流)
题意:给定 n 个点,m 条有向边,如果有向边的标号是1的话,就表示该边的上界下界都为容量 ,如果有向边的标号为0的哈,表示该边的下界为0,上界为容量 ,现在问,从 1 到 n 的最小流是多少,并输出 ...
- loj #117. 有源汇有上下界最小流
题目链接 有源汇有上下界最小流,->上下界网络流 注意细节,边数组也要算上后加到SS,TT边. #include<cstdio> #include<algorithm> ...
- LOJ.117.[模板]有源汇有上下界最小流(Dinic)
题目链接 有源汇有上下界最小流 Sol1. 首先和无源汇网络流一样建图,求SS->TT最大流: 然后连边(T->S,[0,INF]),再求一遍SS->TT最大流,答案为新添加边的流量 ...
- BZOJ1458:士兵占领(有上下界最小流)
Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放 ...
- HDU 3157 Crazy Circuits (有源汇上下界最小流)
题意:一个电路板,上面有N个接线柱(标号1~N) 还有两个电源接线柱 + - 然后是 给出M个部件正负极的接线柱和最小电流,求一个可以让所有部件正常工作的总电流. 析:这是一个有源汇有上下界的 ...
- hdu3157有源汇上下界最小流
题意:有源汇上下界最小流裸题,主要就是输入要用字符串的问题 #include<bits/stdc++.h> #define fi first #define se second #defi ...
随机推荐
- codeforces 676A A. Nicholas and Permutation(水题)
题目链接: A. Nicholas and Permutation time limit per test 1 second memory limit per test 256 megabytes i ...
- hdu 4403 简单搜索
思路:分等号左边和右边进行搜索 #include<iostream> #include<cstdio> #include<cstring> #include< ...
- Jquery插件(CKEditor)
描述 在html页面实现像word一样的编辑功能(可视化HTML编辑器) 解决方法 ckeditor插件官方网站 http://ckeditor.com/ 使用 1:去官方下载ckeditor插件,添 ...
- Linq To Csv 实例简说
http://www.codeproject.com/Articles/25133/LINQ-to-CSV-library 详细源代码在这里 https://github.com/mperdeck/L ...
- MongoDB - Introduction of the mongo Shell
Introduction The mongo shell is an interactive JavaScript interface to MongoDB. You can use the mong ...
- ASP.NET缓存全解析5:文件缓存依赖 转自网络原文作者李天平
这种策略让缓存依赖于一个指定的文件,通过改变文件的更新日期来清除缓存. ///<summary> /// 获取当前应用程序指定CacheKey的Cache对象值 ///</summa ...
- 无需操作系统和虚拟机,直接运行Python代码
Josh Triplett以一个“笑点”开始了他在PyCon 2015上的演讲:移植Python使其无需操作系统运行:他和他的英特尔同事让解释器能够在GRUB引导程序.BIOS或EFI系统上运行.连演 ...
- 熔断器设计模式<转>
熔断器设计模式 如果大家有印象的话,尤其是夏天,如果家里用电负载过大,比如开了很多家用电器,就会”自动跳闸”,此时电路就会断开.在以前更古老的一种方式是”保险丝”,当负载过大,或者电路发生故障或异常时 ...
- C#实现自定义事件,用于监视变量变化
很多时候我们需要程序具有一种功能,就是当满足某一条件时触发某个动作,使用C#的事件机制就可以达到这个目的下面的例子是一个很好的演示. 这段代码实现了对一个变量的监视,一旦变量发生改变,就触发动作 定义 ...
- 如何用C#代码查找某个路径下是否包含某个文件
string path = "f:\\哈哈"; if (Directory.Exists(path)) { MessageBox.Show("存在文件夹") ...