ZOJ 3229 有上下界最大流
1: /**
2: ZOJ 3229 有上下界的最大流
3: 两次求最大流的过程,非二分
4: 有源汇上下界的最大流问题, 首先连接 sink -> src, [0,INF].
5: 根据net的正负,来建立 Supersrc 与 supersink 之间的边,做一次 maxflow.
6: 若所有的Supersrc 与 Supersink满流,则说明存在可行流.
7: 然后删除 sink -> src之间的边.(cap 置零即可). 从src -> sink 做一次最大流.
8: 两次最大流的和即为整个网络的最大流.
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 1500 // vertex
20: #define E V *80 // 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: // girl 0-m-1, day m,m+n-1, src m+n, sink m+n+1. all m+n+2 point
113: void solve()
114: {
115: int N,M; // n days m girl
116: while(scanf("%d%d", &N,&M) != EOF)
117: {
118: e = 0;
119: memset(head, -1, sizeof(head));
120: memset(net, 0, sizeof(net));
121: int G; src = M+N, sink = M+N+1;
122: for(int i=0; i<M; i++)
123: {
124: scanf("%d", &G);
125: addedge(i,sink,INF-G, G,INF);
126: net[i] -= G;
127: net[sink] += G;
128: }
129: vector<int> CE;
130: for(int i=0; i<N; i++)
131: {
132: int C,D; scanf("%d%d", &C,&D);
133: addedge(src, M+i, D, 0, D);
134: for(int j=0; j<C; j++)
135: {
136: int T,L,R; scanf("%d%d%d", &T,&L,&R);
137: CE.push_back(e);
138: addedge(M+i,T,R-L, L,R);
139: net[M+i] -= L;
140: net[T] += L;
141: }
142: }
143: int spec = e;
144: // 添加从sink -> src 容量为INF的边
145: addedge(sink, src, INF,0,INF);
146: src = M+N+2; sink = M+N+3; // M+N+4 point
147: int rangea = e;
148: for(int i=0; i<M+N+2; i++)
149: {
150: if(net[i] >= 0) addedge(src, i, net[i]);
151: else addedge(i, sink,-net[i]);
152: }
153: double ret = 0;
154: int rangeb = e;
155: // 从super src ->super sink 做一次最大流
156: ret+=ISAP(M+N+4);
157: bool flag = true;
158: // 判断是否满流
159: for(int i= rangea; i<rangeb; i+=2)
160: {
161: if(edge[i].w !=0)
162: {
163: flag = false;
164: break;
165: }
166: }
167: if(flag)
168: {
169: // 修改 src sink,然后把 从sink -> src 的边删除
170: src = M+N; sink = M+N+1;
171: edge[spec].w = 0; edge[spec+1].w = 0;
172: // 从 src->sink 做一次最大流
173: ret += ISAP(M+N+2);
174: int tmp = ret;
175: printf("%d\n", tmp);
176: for(int i=0; i<CE.size(); i++)
177: printf("%d\n", edge[CE[i]+1].lb + edge[CE[i]+1].w);
178: }else printf("-1\n");
179: cout<<endl;
180: }
181: }
182: }sap;
183:
184: int main()
185: {
186: // freopen("1.txt","r",stdin);
187: sap.solve();
188: return 0;
189: }
.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; }
ZOJ 3229 有上下界最大流的更多相关文章
- Shoot the Bullet ZOJ - 3229有上下界网络流
Code: #include<cstdio> #include<algorithm> #include<vector> #include<queue> ...
- ZOJ 3229 Shoot the Bullet [上下界最大流]
ZOJ 3229 Shoot the Bullet 题意:此生无悔入东方 上下界最大流 spj挂掉了我也不知道对不对,把代码放这里吧以后正常了可能会评测一下 #include <iostream ...
- 【有源汇上下界最大流】ZOJ 3229 Shoot the Bullet
题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3229 题目大意: n天给m个女孩拍照(1<=n<= ...
- ZOJ 3229 Shoot the Bullet(有源汇上下界最大流)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3442 题目大意: 一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝给 ...
- zoj 3229 Shoot the Bullet(有源汇上下界最大流)
Shoot the Bullethttp://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3442 Time Limit: 2 Second ...
- ZOJ - 3229 Shoot the Bullet (有源汇点上下界最大流)
题意:要在n天里给m个女生拍照,每个女生有拍照数量的下限Gi,每天有拍照数量的上限Di,每天当中每个人有拍照的上限Lij和Rij.求在满足限制的基础上,所有人最大能拍多少张照片. 分析:抛开限制,显然 ...
- ZOJ 3229 Shoot the Bullet(有源汇的上下界最大流)
Description Gensokyo is a world which exists quietly beside ours, separated by a mystical border. It ...
- [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流
poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...
- ZOJ 2314 - Reactor Cooling - [无源汇上下界可行流]
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2314 The terrorist group leaded by ...
随机推荐
- Page.ClientScript.RegisterStartupScript
Page.ClientScript.RegisterStartupScript方法最初可用的选项之一就是使用一个可实现此功能的 .NET 类来注册脚本块. 第一个是 RegisterStartupSc ...
- Fuck Sharepoint 2013
最近遇到一个貌似是bug的问题,每次点击页面的时候页面的地址多出一行/_layouts/15/start.aspx#/ 然后跑到google上搜索出解决方案, 地址:http://social.tec ...
- jQuery.Hotkeys - lets you watch for keyboard events anywhere in your code supporting almost any key combination
About jQuery Hotkeys is a plug-in that lets you easily add and remove handlers for keyboard events a ...
- BaseAdapter&ArrayAdapter在ListView中应用
一:BaseAdapter:共同实现的基类的适配器,是ArrayAdapter SimpleAdapter等的父类, 一般用于比较复杂的ListView,扩展性强. 详细信息可查看谷歌官方API:ht ...
- 实现类似微信的延迟加载的Fragment——LazyFragment
参考微信,使用ViewPager来显示不同的tab,每个tab是一个Fragment, 假设有3个tab,对应的fragment是FragmentA.FragmentB.FragmentC 需要实现的 ...
- SQL批量修改表名
SELECT NAME FROM SYS. ALL_OBJECTS WHERE TYPE= 'U' ORDER BY MODIFY_DATE DESC --查询所有表名 SELECT NAME FRO ...
- javascript中的闭包。
function todo() { var var1 = 1; (function () { var var2 = var1 + 1; alert(var2); })(); } todo(); (fu ...
- web.config connectionStrings 数据库连接字符串的解释
先来看一下默认的连接SQL Server数据库配置<connectionStrings> <add name="LocalSqlServer" connect ...
- Apache2.4 与 PHP 5.5 64位版的安装配置
我的环境:windows7 旗舰版 64位 首先下载相关文件: php 5.5.0 windows 64版 http://windows.php.net/download/#php-5.5 (选择 6 ...
- 深刻理解C#中资源释放
今天我的一个朋友看到我写的那篇<C#中用AJAX验证用户登录>时,给我指出了点小毛病.就是在用户登录时,如果用户登录失败,在下面这段代码中,都会new出来一个User对象,如果连续登录失败 ...