时间限制: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. Linux Shell编程(29)——函数

    和"真正的"编程语言一样, Bash也有函数,虽然在某些实现方面稍有些限制. 一个函数是一个子程序,用于实现一串操作的代码块,它是完成特定任务的"黑盒子". 当 ...

  2. Delphi webservice 定义 转

    webservice   Web Services是由企业发布的完成其特定商务需求的在线应用服务,其他公司或应用软件能够通过Internet来访问并使用这项在线服务. 简介 它是一种构建应用程序的普遍 ...

  3. [YUM]Public key for *.rpm is not installed

    解决办法: 此时要导入rpm的签名信息即可 以root登录,执行下面命令 # rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release

  4. zabbix oracle监控插件orabbix部署安装

    1,下载orabbix插件包(插件包同时满足在大部分POSIX-linux及unix和大部分版本的windows下运行,玩转类似但不等同于Tomcat) wget http://www.smartma ...

  5. Unity3D开发类似保龄球游戏

    先学习一些基本的脚本实现: 1.动态创建物体.默认位置是(0,0)位置 GameObject goNew = GameObject.CreatePrimitive(PrimitiveType.Cube ...

  6. Redis学习记录之Java中的初步使用

    1.关于Redis redis下载地址:<span style="font-family: Arial, Helvetica, sans-serif;">http:// ...

  7. PHP小题目 求 1*3+5*7+…+97*99的值

    下面是另外两种比较基础的方法实现的代码

  8. Away3d 骨骼动画优化

    很多朋友说Away3D 的骨骼数限制在32根,确切的说应该是Stage3D 的限制.在 AGAL2.0之前 VC寄存器是128个,每个vc常量寄存器最大只能容纳4位,transform占用一个4*4的 ...

  9. Java基础知识强化之集合框架笔记17:List集合的特有的遍历功能

    1. List集合的特有遍历功能: size()和 get()方法结合使用 2. 代码示例: package cn.itcast_03; import java.util.ArrayList; imp ...

  10. 使用SqlAlchemy时如何方便的取得dict数据、dumps成Json

    使用Sqlalchemy可以方便的从数据库读取出python对象形式的数据(吐槽:说实话对象形式也没多方便,还不如我之前从关系型数据库直接读取出dict形式的数据用起来方便,具体参见我以前的文章htt ...