时间限制: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. HDU-4570 Multi-bit Trie

    http://acm.hdu.edu.cn/showproblem.php?pid=4570 Multi-bit Trie Time Limit: 2000/1000 MS (Java/Others) ...

  2. window.alert弹出处理

    # -*- coding:utf-8 -*- """ window.alert 处理 """ from selenium import we ...

  3. supesite 模板相关文档记录

    文件说明:http://wenku.baidu.com/view/69c07820af45b307e87197ac.html 开发文档:http://wenku.baidu.com/view/35f6 ...

  4. 邮件发送小demo

    //send email public static bool SendEmail() { //实例化发件人地址 MailAddress from = new MailAddress("aa ...

  5. IronPython fail to add reference to WebDriver.dll

    在使用Ironpython引用WebDriver程序集做web自动化时碰到这个问题,出问题的代码很简单,如下: import sys import clr clr.AddReferenceToFile ...

  6. Ural 1043 Cover the Arc

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1043 题目大意:一个2000*2000方格坐标,x,y范围都是[-1000,1000]. ...

  7. 【设计模式 - 16】之迭代器模式(Iterator)

    1      模式简介 迭代器模式是JAVA中非常常用的模式,List.Map.Set等常见集合中都封装了迭代器Iterator. 迭代器模式的介绍: 迭代器模式用于顺序访问集合对象中的元素,而不需要 ...

  8. MySQL (DCL)

    DCL语句 :数据库系统管理员使用,也就是数据库管理员 root 可以添加用户.删除用户.授予和限制用户权限,这些用户的信息可以在数据库的mysql数据库中查询到 1.查看用户信息     1.用ro ...

  9. hive运行query语句时提示错误:org.apache.hadoop.ipc.RemoteException: java.io.IOException: java.io.IOException:

    hive> select product_id, track_time from trackinfo limit 5; Total MapReduce jobs = 1 Launching Jo ...

  10. Thread和Runnable差别

    继承Thread类的,我们相当于拿出三件事即三个卖票10张的任务分别分给三个窗体,他们各做各的事各卖各的票各完毕各的任务.由于MyThread继承Thread类.所以在new MyThread的时候在 ...