时间限制:0.5s

空间限制:4M

题意:

  有一个由管道组成的网络,有n个节点(n不大于100),1号节点可以制造原料,最后汇集到n号节点。原料通过管道运输。其中有一些节点有管道连接,这些管道都有着最大的流量限制,其中有一些管道必须充满。求1号节点最小的制造原料速度。如果原料不能运输到n,输出“Impossible”


Solution

第一道有上下界的网络流。从理解不太深刻,wa了很多次后。完全理解了有上下界网络流的算法。

首先,要构造一个伴随网络,由此判断,是否能让所有的下界满足,并连通源汇点。

由于是求最小流,我们需要知道,是否能从汇点找到一条到源点的增广路。使得最大流减小。

这时可能求出负流flow,只要新加一个节点0,添加到汇点的一条容量为-flow的边,即可让负流变为0;

具体的构造方法在程序注释里。

/*
有容量上下界的最大流算法
1)cap(u,v)为u到v的边的容量
2)Gup(u,v)为u到v的边流量上界
3)Glow(u,v)为u到v的边流量下界
4)st(u)代表点u的所有出边的下界之和
5)ed(u)代表点u的所有入边的下界之和
6)S为源点,T为汇点
新网络D的构造方法:
1)加入虚拟源点SS,ST
2)如果边(u,v)的容量cap(u,v)=Gup(u,v)-Glow(u,v)
3)对于每个点v,加入边(SS,v)=ed(v);
4)对于每个点u,加入边(u,ST)=st(u);
5)cap(T,S)=+∞;
6)tflow为所有边的下界之和
求SS到ST的最大流,若最大流不等于tflow,则不存在可行流,此问题无解。
在新网络D中去掉所有与SS,ST相连的边。求最大流。
最后将两个流值相加
最小流,第二次最大流从T到S运行。 */
#include <iostream>
#include <cstdio>
#include <cstring>
#define ms(a,b) memset(a,b,sizeof a)
using namespace std;
const int INF = ;
struct node {
int u, v, c, next;
} edge[INF * INF << ];
int Gup[INF][INF], Glow[INF][INF], st[INF], ed[INF], cap[INF][INF], tflow;
int pHead[INF*INF], SS, ST, S, T, nCnt, ans;
//同时添加弧和反向边, 反向边初始容量为0
void addEdge (int u, int v, int c) {
edge[++nCnt].v = v, edge[nCnt].u = u, edge[nCnt].c = c;
edge[nCnt].next = pHead[u]; pHead[u] = nCnt;
edge[++nCnt].v = u, edge[nCnt].u = v, edge[nCnt].c = ;
edge[nCnt].next = pHead[v]; pHead[v] = nCnt;
}
int SAP (int pStart, int pEnd, int N) {
int numh[INF], h[INF], curEdge[INF], pre[INF];
int cur_flow, flow_ans = , u, neck, i, tmp;
ms (h, ); ms (numh, ); ms (pre, -);
for (i = ; i <= N; i++) curEdge[i] = pHead[i];
numh[] = N;
u = pStart;
while (h[pStart] <= N) {
if (u == pEnd) {
cur_flow = 1e9;
for (i = pStart; i != pEnd; i = edge[curEdge[i]].v)
if (cur_flow > edge[curEdge[i]].c) neck = i, cur_flow = edge[curEdge[i]].c;
for (i = pStart; i != pEnd; i = edge[curEdge[i]].v) {
tmp = curEdge[i];
edge[tmp].c -= cur_flow, edge[tmp ^ ].c += cur_flow;
}
flow_ans += cur_flow;
u = neck;
}
for ( i = curEdge[u]; i != ; i = edge[i].next) {
if (edge[i].v > N) continue; //重要!!!
if (edge[i].c && h[u] == h[edge[i].v] + ) break;
}
if (i != ) {
curEdge[u] = i, pre[edge[i].v] = u;
u = edge[i].v;
}
else {
if ( == --numh[h[u]]) continue;
curEdge[u] = pHead[u];
for (tmp = N, i = pHead[u]; i != ; i = edge[i].next) {
if (edge[i].v > N) continue; //重要!!!
if (edge[i].c) tmp = min (tmp, h[edge[i].v]);
}
h[u] = tmp + ;
++numh[h[u]];
if (u != pStart) u = pre[u];
}
}
return flow_ans;
}
int solve (int n) {
//建立伴随网络
SS = n + , ST = n + ;
for (int i = ; i <= n; i++) {
if (ed[i]) addEdge (SS, i, ed[i]);
if (st[i]) addEdge (i, ST, st[i]);
}
//T到S添加一条无限容量边
addEdge (T, S, 0x7ffffff);
//判断可行流
int tem = SAP (SS, ST, ST);
if (tem != tflow) return -;
else {
edge[nCnt].c = edge[nCnt - ].c = ; //删除S到T的无限容量边
int kkk = SAP (T, S, T);
return ;
}
}
int n, m, x, y, c, sta;
int main() {
/*
建图,前向星存边,表头在pHead[],边计数 nCnt.
S,T分别为源点和汇点
*/
scanf ("%d %d", &n, &m);
nCnt = ;
for (int i = ; i <= m; i++) {
scanf ("%d %d %d %d", &x, &y, &c, &sta);
Gup[x][y] = c;
if (sta) {
Glow[x][y] = c;
st[x] += c, ed[y] += c;
tflow += c;
}
addEdge (x, y, Gup[x][y] - Glow[x][y]);
}
S = , T = n;
ans = ;
if (solve (n) > ) {
for (int i = ; i <= nCnt; i += ) {
if (edge[i].v <= T && edge[i].u == )
ans += Gup[edge[i].u][edge[i].v] - edge[i].c;
if (edge[i].u <= T && edge[i].v == )
ans -= Gup[edge[i].u][edge[i].v] - edge[i].c;
}
if (ans < ) {
S = ;
addEdge (S, , -ans);
ans = ;
SAP (S, T, T);
}
printf ("%d\n", ans);
for (int i = ; i <= * m; i += )
printf ("%d ", Gup[edge[i].u][edge[i].v] - edge[i].c);
}
else puts ("Impossible");
return ;
}

SGU 176.Flow construction (有上下界的最大流)的更多相关文章

  1. sgu 176 有源汇有上下界的最小流模板题

    /*参考博文:http://hi.baidu.com/dragon_eric123/item/82e259200ece744046996282 有上下界的有源最小流 */ #include<st ...

  2. SGU 176 Flow construction(有源汇上下界最小流)

    Description 176. Flow construction time limit per test: 1 sec. memory limit per test: 4096 KB input: ...

  3. Flow construction SGU - 176 有源汇有上下界最小流 二分法和回流法

    /** 题目:Flow construction SGU - 176 链接:https://vjudge.net/problem/SGU-176 题意: 有源汇有上下界的最小流. 给定n个点,m个管道 ...

  4. sgu 176 Flow construction(有源汇的上下界最小流)

    [题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11025 [模型] 有源汇点的上下界最小流.即既满足上下界又满足 ...

  5. SGU 176 Flow construction (有源有汇有上下界最小流)

    题意:给定 n 个点,m 条有向边,如果有向边的标号是1的话,就表示该边的上界下界都为容量 ,如果有向边的标号为0的哈,表示该边的下界为0,上界为容量 ,现在问,从 1 到 n 的最小流是多少,并输出 ...

  6. SGU 176 Flow construction【有上下界最小流】

    正好考到了所以翻一些题来做--猛然发现搞了半个月的网络流却没做两道上下界(不过这种题好像是比较少233) 首先建立超级源汇ss,tt,没限制的边照常连,对于有限制的边(u,v,mn,mx),连接(u, ...

  7. sgu 194 无源汇有上下界的最大流(最大流模板dinic加优化)

    模板类型的题具体参考国家集训队论文:http://wenku.baidu.com/view/0f3b691c59eef8c75fbfb35c.html 参考博客:http://blog.csdn.ne ...

  8. HDU Destroy Transportation system(有上下界的可行流)

    前几天正看着网络流,也正研究着一个有上下界的网络流的问题,查看了很多博客,觉得下面这篇概括的还是相当精确的: http://blog.csdn.net/leolin_/article/details/ ...

  9. 【UVALive - 5131】Chips Challenge(上下界循环费用流)

    Description A prominent microprocessor company has enlisted your help to lay out some interchangeabl ...

随机推荐

  1. (转载)PHP isset()函数作用

    (转载)http://www.cnblogs.com/neve/archive/2011/03/21/1990165.html isset函数是检测变量是否设置. 格式:bool isset ( mi ...

  2. codeforce ---A. Milking cows

    A. Milking cows time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  3. 折腾iPhone的生活——iPhone 5s 开启 assistive touch 后卡顿的问题

    刚刚入手我的国行iPhone5s土狗灰,感觉倍棒~ 但是一上手就发现了一个问题:卡顿. 卡顿不仅体现在日常使用中,游戏中更加严重,当我玩水果忍者的时候,会发现切水果的画面都变得不流畅起来,这是拥有64 ...

  4. DBI接口和DPI接口的区别

    1)DBI接口 A,也就是通常所讲的MCU借口,俗称80 system接口.The lcd interface between host processor and LCM device list a ...

  5. 【转载】Manacher算法

    本文原创:http://www.cnblogs.com/BigBallon/p/3816890.html只为了记录学习,不为抄袭!http://www.felix021.com/blog/read.p ...

  6. UVa12171 hdu2771 UVaLive4291 Sculpture

    填坑系列(p.171) orz rjl 代码基本和rjl的一样 #include<cstdio> #include<cstring> #include<cstdlib&g ...

  7. Mina学习之与Spring整合

    本章中演示在Spring中整合Mina,为了整合到Spring,需要做以下几个步骤: 1. 设置IoHandler <bean id="trapHandler" class= ...

  8. 树莓派入手(烧写系统,调整分区,配置Java环境,串口GPS配置) 分类: Raspberry Pi 2015-04-09 21:13 145人阅读 评论(0) 收藏

    原来的tf卡无故启动不起来,检查发现其文件系统分区使用率为0%. 数据全部丢失!!!!! 血的教训告诉我们备份文件系统的重要性,一切需要重头来.... 烧录系统 安装系统有两种方式, NOOBS工具安 ...

  9. ThinkPHP 中M方法和D方法的具体区别(转)

    M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...

  10. oracle 常用博客网址

    使用oradebug修改数据库scn – 提供专业ORACLE技术咨询和支持@Phone13429648788 - 惜分飞 Solaris上使用DTrace进行动态跟踪 老熊的三分地-Oracle及数 ...