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 ...
随机推荐
- 怒刷DP之 HDU 1087
Super Jumping! Jumping! Jumping! Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64 ...
- Java操作XML的工具类
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.Inp ...
- Oracle数据库作业-3 查询
1. 查询Student表中的所有记录的Sname.Ssex和Class列.
- Java作业
1.实现一个名为Person的类和它的子类Employee,Employee有两个子类Faculty和Staff.具体要求如下: (1)Person类中的属性有:姓名name(String类型),地址 ...
- 我与Bootstrap
接触bootstrap是因为一个项目.实在是不了解前端.但是公司又不招前端工程师,没有办法,我这个后端工程师被赶鸭子上架了. 做这个项目之前,只是简单的在网上看了一些bootstrap教学视频.然后拿 ...
- oracle发送邮件
1.创建发送邮件的存储过程 CREATE OR REPLACE PROCEDURE send_mail(p_recipient VARCHAR2, -- 邮件接收人 p_subject VARCHAR ...
- 【学习笔记】【C语言】指向结构体的指针
1.指向结构体的指针的定义 struct Student *p; 2.利用指针访问结构体的成员 1> (*p).成员名称 2> p->成员名称 3.代码 #include < ...
- 【学习笔记】【C语言】二维数组
1. 什么是二维数组 一个数组能表示一个班人的年龄,如果想表示很多班呢? 什么是二维数组?int ages[3][10]; 三个班,每个班10个人 相当于3行10列 相当于装着3个一维数组 二维数组是 ...
- 将DataTable格式化为json字符串返回
一般用于ajax局部刷新的使用比较多,通过查询得到了DataTable数据,要想将数据放回需要将DataTable转换为json格式,以下为转换的调用函数: string json = "& ...
- CSS Sprite 雪碧图制作
CSS Sprite 雪碧图,简单来说就是: 为了提高网页的性能,减少加载次数,将一些不会经常随网站内容变化的小图标,集中放在一张大图上,将该图应作为background-image 嵌入页面中,在需 ...