Cogs 12 运输问题2 (有上下界网络流)

  1 #include <cstdlib>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <cstdio>
  6 #include <vector>
  7
  8 using namespace std;
  9
 10 const int N = 100 +  5;
 11 const int oo = 0x3f3f3f3f;
 12
 13 struct Edge {
 14   int from, to, cap, flow;
 15 };
 16
 17 struct Dinic {
 18   int n, m, s, t;
 19   int dis[N], cur[N], que[N << 1];
 20   bool vis[N];
 21   vector <Edge> edges;
 22   vector <int> G[N];
 23
 24   void add(int from, int to, int cap) {
 25     edges.push_back((Edge) {from, to, cap, 0});
 26     edges.push_back((Edge) {to, from, 0, 0});
 27     m = edges.size();
 28     G[from].push_back(m - 2);
 29     G[to].push_back(m - 1);
 30   }
 31
 32   bool bfs() {
 33     int head = 1, tail = 1;
 34
 35     memset(vis, false, sizeof vis);
 36     dis[s] = 0; vis[s] = true; que[head] = s;
 37     while(head <= tail) {
 38       int x = que[head];
 39
 40       for(int i = 0; i < (signed) G[x].size(); ++ i) {
 41         Edge &e = edges[G[x][i]];
 42
 43         if(!vis[e.to] && e.cap > e.flow) {
 44           vis[e.to] = true;
 45           dis[e.to] = dis[x] + 1;
 46           que[++ tail] = e.to;
 47         }
 48       }
 49       ++ head;
 50     }
 51     return vis[t];
 52   }
 53
 54   int dfs(int x, int a) {
 55     if(x == t || a == 0) return a;
 56
 57     int flw = 0, f;
 58
 59     for(int &i = cur[x]; i < (signed) G[x].size(); ++ i) {
 60       Edge &e = edges[G[x][i]];
 61
 62       if(dis[e.to] == dis[x] + 1 && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0) {
 63         e.flow += f; edges[G[x][i] ^ 1].flow -= f; flw += f; a -= f;
 64         if(a == 0) break;
 65       }
 66     }
 67     return flw;
 68   }
 69
 70   int MaxFlow(int s, int t) {
 71     this->s = s; this->t = t;
 72
 73     int flw = 0;
 74
 75     while(bfs()) {
 76       memset(cur, 0, sizeof cur);
 77       flw += dfs(s, oo);
 78     }
 79     return flw;
 80   }
 81 }net;
 82
 83 int n, M[N];
 84
 85 int main() {
 86 #ifndef ONLINE_JUDGE
 87   freopen("maxflowb.in", "r", stdin);
 88   freopen("maxflowb.out", "w", stdout);
 89 #endif
 90
 91   int Up, Down;
 92
 93   scanf("%d", &n); net.n = n + 1;
 94   for(int i = 1; i <= n; ++ i) {
 95     for(int j = 1; j <= n; ++ j) {
 96       scanf("%d%d", &Down, &Up);
 97       M[i] -= Down; M[j] += Down;
 98       net.add(i, j, Up - Down);
 99     }
100   }
101   net.add(n, 1, oo);
102   for(int i = 1; i <= n; ++ i) {
103     if(M[i] > 0) {
104       net.add(0, i, M[i]);
105     }
106     else if(M[i] < 0){
107       net.add(i, n + 1, -M[i]);
108     }
109   }
110   net.MaxFlow(0, n + 1);
111   printf("%d\n", net.MaxFlow(1, n));
112
113 #ifndef ONLINE_JUDGE
114   fclose(stdin); fclose(stdout);
115 #endif
116   return 0;
117 }

Cogs 12

连边方式见图。

时间: 2024-10-09 21:37:30

Cogs 12 运输问题2 (有上下界网络流)的相关文章

有上下界的网络流2-有源汇带上下界网络流ZOJ3229

ZOJ3229题目大意:一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝可以和C个女神拍照,每天拍照数不能超过D张,而且给每个女神i拍照有数量限制[Li,Ri],对于每个女神n天的拍照总和不能少于Gi,如果有解求屌丝最多能拍多少张照,并求每天给对应女神拍多少张照:否则输出-1. 解题思路:        1.增设一源点st,汇点sd,st到第i天连一条上界为Di下界为0的边,每个女神到汇点连一条下界为Gi上界为正无穷的边,对于每一天,当天到第i个女孩连一条[Li,Ri]的边.        2.

acdream 1211 Reactor Cooling 【上下界网络流 + 输出流量】

题目:acdream 1211 Reactor Cooling 分类:无源无汇的有上下界网络流. 题意: 给n个点,及m根pipe,每根pipe用来流躺液体的,单向的,每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体,里面流躺物质. 并且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题),同时最小不能低于Li. 例如: 46(4个点,6个pipe) 12 1 3 (1->2上界为3,下界为1) 23 1 3

ZOJ 2314 Reactor Cooling 无源汇有上下界网络流

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 题意:给出N个点,M条边的有向图,每条边的有上下界规定,问是否存在一个可行流满足条件,如果满足输出YES并输出每条边的流量. 如果不满足输出NO. 根据周源的<一种简易的方法求解流量有上下界的网络中网络流问题> 无源汇上下界网络流的做法是: 设边u->v的下界是B(u,v),上界是C(u,v). 设M(i)为对于i结点的流入i的下界总和-流出i的下界总

[BZOJ2502]清理雪道 有上下界网络流(最小流)

2502: 清理雪道 Time Limit: 10 Sec  Memory Limit: 128 MB Description 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞机,每次飞行可以从总部带一个人降落到滑雪场的某个地点,然后再飞回总部.从降落的地点出发,这个人可以顺着斜坡向下滑行,并清理他所经过的雪道. 由于每次飞行的耗费是固定的,为了最小化耗费

【有上下界网络流】【ZOJ】2314 Reactor Cooling

[算法]有上下界网络流-无源汇(循环流) [题解] 无源汇网络流相当于重建图后跑最大流. 循环流要求每个点(或边)的流入量和流出量相等. http://www.cnblogs.com/liu-runda/p/6262832.html http://hzwer.com/3356.html 入度>出度时(in[x]>0)时,需要流出去,所以从源向点引一条边,引诱它流出去. 入度<出度时(in[x]<0)时,需要流进来,所以从点向汇引一条边,引诱它流进来. 为何这样正确?源和汇的作用只是

上下界网络流总结

1.无源汇上下界可行流 对于(u,v)有向边,上界为a,下界为b 构图方法为: (1) ss 到 v 容量为 b (2) u 到 tt 容量为 b (3) u 到 v 容量为 a-b 求ss-tt最大流,当且仅当 maxflow=sigma(i,t)=sigma(s,i) 时 存在可行流 2.有源汇上下界最小流 如果发现原图无源汇,要先转化为有源汇 其他点如1方法,建图,另加 t-s 容量为 inf 求一遍 ss-tt最大流,此时s-t的流量为 t-s这条边的反向边的流量,记为 x 在残量网络中

ZOJ Problem Set - 3229 Shoot the Bullet 【有上下界网络流+流量输出】

题目:ZOJ Problem Set - 3229 Shoot the Bullet 分类:有源有汇有上下界网络流 题意:有 n 天和 m 个girls,然后每天给一部分girls拍照,每个girls 有拍照的下限,即最少要拍这么多张,然后每天有k个女孩拍照,摄影师最多可以拍num张,然后 k 个女该每天拍照数量值有上下限,然后问你有没有满足这样条件的给女孩拍照的最大方案,然后按照输入输出每天给女孩拍照的张数. 做这道题目推荐先做:这儿 分析:首先它让你判断能不能满足条件. 按照题目给出的条件很

Note:上下界网络流的理解

无源汇可行流 弧流量限制条件 b(u,v)<=f(u,v)<=c(u,v),(u,v)∈E 不妨设f(u,v)=b(u,v)+f1(u,v), Σ( b(u,v)+f1(u,v) ) = Σ( b(v,w)+f1(v,w) ) Σ b(u,v) - Σ b(v,w) = Σ f1(v,w) - Σf1(u,v) 若存在可行流,0<=f1(u,v)<=c(u,v)-b(u,v),且保证下界流流满. 可以加超级源S,超级汇T. 假定某条边(u,v)的流量限制是[b,c],等价于S→v流

hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )

题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到S的路径的费用和 + 重建这些T到S的双向路径的费用和. 思路1: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center&quo

hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流判断 )

题意:有n个点和m条有向边构成的网络,每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏所有S到T的路径的费用和 > 毁坏所有T到S的路径的费用和 + 重建这些T到S的双向路径的费用和. 思路1: 然后这个无源汇带上下界网络流的可行流问题的求解方法见这里~~ 建图就是上面说的那样啦~最后判断有没有可行流就是求一下我们所构造的这个新的网络的最大流~然后判断一下这个最大流是否满流~(即判断最大流是否和附加源点的流出总量相等~~) cod