[刷题]HDU3157
来源:互联网 发布:上海雨人软件 编辑:程序博客网 时间:2024/05/29 04:24
两道有上下界有源汇最小流。
步骤之前写的笔记里有。但是原理。。。确实不太懂。
步骤:
1. 按照无源汇有上下界的最大流的做法找出可行流(但不要建立t->s);
2. 添加t->s,流量上界INF;
3. 再次运行最大流,找出ss->st可行流;
4. 若ss不满载,则无可行流。反之,最小流为t->s的流量,每条边的流量为逆向边的流量(加上下界b)。
SGU176 - Flow construction
//下界网络流#include<iostream>#include<queue>#include<vector>#include<cstring>#include<algorithm>#define INF 0x3f3f3f3f#define Maxn 200using namespace std;struct Edge { int c, f, id; unsigned v, flip; Edge(unsigned v, int c, int f, unsigned flip, int id) :v(v), c(c), f(f), flip(flip), id(id) {}};class Dinic {public: bool b[Maxn]; int a[Maxn]; unsigned p[Maxn], cur[Maxn], d[Maxn]; vector<Edge> G[Maxn]; unsigned s, t; void Init(unsigned n) { for (int i = 0; i <= n; ++i) G[i].clear(); } void AddEdge(unsigned u, unsigned v, int c, int id) { G[u].push_back(Edge(v, c, 0, G[v].size(),0)); G[v].push_back(Edge(u, 0, 0, G[u].size() - 1, id)); // 使用无向图时将0改为c即可 } bool BFS() { unsigned u, v; queue<unsigned> q; memset(b, 0, sizeof(b)); q.push(s); d[s] = 0; b[s] = 1; while (!q.empty()) { u = q.front(); q.pop(); for (auto it = G[u].begin(); it != G[u].end(); ++it) { Edge &e = *it; if (!b[e.v] && e.c>e.f) { b[e.v] = 1; d[e.v] = d[u] + 1; q.push(e.v); } } } return b[t]; } int DFS(unsigned u, int a) { if (u == t || a == 0) return a; int flow = 0, f; for (unsigned &i = cur[u]; i<G[u].size(); ++i) { Edge &e = G[u][i]; if (d[u] + 1 == d[e.v] && (f = DFS(e.v, min(a, e.c - e.f)))>0) { a -= f; e.f += f; G[e.v][e.flip].f -= f; flow += f; if (!a) break; } } return flow; } int MaxFlow(unsigned s, unsigned t) { int flow = 0; this->s = s; this->t = t; while (BFS()) { memset(cur, 0, sizeof(cur)); flow += DFS(s, INF); } return flow; }};int Flow[10000+23];int N, M;int Dif[Maxn];int main() { ios::sync_with_stdio(false); while (cin >> N >> M) { const int ss = N + 1, st = N + 2; memset(Dif, 0, sizeof(Dif)); memset(Flow, 0, sizeof(Flow)); Dinic Din; Din.Init(N); int u, v, b, c; for (int i = 1; i <= M; ++i) { cin >> u >> v >> c >> b; if (b) { b = c; Dif[u] -= b; Dif[v] += b; Flow[i] = b; } else Din.AddEdge(u, v, c - b, i); } int sum = 0; for (int i = 1; i <= N; ++i) { if (Dif[i] > 0) { Din.AddEdge(ss, i, Dif[i], 0); sum += Dif[i]; } if (Dif[i] < 0) Din.AddEdge(i, st, -Dif[i], 0); } int ans = Din.MaxFlow(ss, st); Din.AddEdge(N, 1, INF, 0); ans += Din.MaxFlow(ss, st); if (sum != ans) cout << "Impossible\n"; else { cout << Din.G[N].rbegin()->f << '\n'; for (int i = 1; i <= N; ++i) for (const auto &e : Din.G[i]) { if (e.id) Flow[e.id] += -e.f; } for (int i = 1; i < M; ++i) cout << Flow[i] << ' '; cout << Flow[M] << '\n'; } } return 0;}
HDU3157 - Crazy Circuits
#include<algorithm>#include<cstring>#include<cstdio>#include<cctype>#include<vector>#include<queue>#include<map>using namespace std;#define INF 0x3f3f3f3fconst int Maxn = 100;int N, M, S, T, SS, ST;int Dif[Maxn];bool QIn(int &x) { char c; while ((c = getchar()) != EOF && (!isdigit(c) && (c != '+'&&c != '-'))); switch (c) { case '+':x = S; return true; case '-':x = T; return true; case EOF: return false; } x = 0; do { x *= 10; x += c - '0'; } while ((c = getchar()) != EOF&&isdigit(c)); return true;}struct Edge { int c, f; unsigned v, flip; Edge(unsigned v, int c, int f, unsigned flip) :v(v), c(c), f(f), flip(flip) {}};class Dinic {private: bool b[Maxn]; int a[Maxn]; unsigned p[Maxn], cur[Maxn], d[Maxn];public: vector<Edge> G[Maxn]; unsigned s, t; void Init(unsigned n) { for (int i = 0; i <= n; ++i) G[i].clear(); } void AddEdge(unsigned u, unsigned v, int c) { G[u].push_back(Edge(v, c, 0, G[v].size())); G[v].push_back(Edge(u, 0, 0, G[u].size() - 1)); //使用无向图时将0改为c即可 } bool BFS() { unsigned u, v; queue<unsigned> q; memset(b, 0, sizeof(b)); q.push(s); d[s] = 0; b[s] = 1; while (!q.empty()) { u = q.front(); q.pop(); for (auto it = G[u].begin(); it != G[u].end(); ++it) { Edge &e = *it; if (!b[e.v] && e.c>e.f) { b[e.v] = 1; d[e.v] = d[u] + 1; q.push(e.v); } } } return b[t]; } int DFS(unsigned u, int a) { if (u == t || a == 0) return a; int flow = 0, f; for (unsigned &i = cur[u]; i<G[u].size(); ++i) { Edge &e = G[u][i]; if (d[u] + 1 == d[e.v] && (f = DFS(e.v, min(a, e.c - e.f)))>0) { a -= f; e.f += f; G[e.v][e.flip].f -= f; flow += f; if (!a) break; } } return flow; } int MaxFlow(unsigned s, unsigned t) { int flow = 0; this->s = s; this->t = t; while (BFS()) { memset(cur, 0, sizeof(cur)); flow += DFS(s, INF); } return flow; }};void Input(Dinic &d) { memset(Dif, 0, sizeof(Dif)); int u, v, b; char c; for (int i = 1; i <= M; ++i) { QIn(u); QIn(v); QIn(b); d.AddEdge(u, v, INF); //由于无上界,直接写INF好了,反正流量不可能达到INF-b Dif[u] -= b; Dif[v] += b; }}int main() { while (~scanf("%d %d",&N,&M) && M) { //N可以等于0! S = N + 1, T = N + 2; SS = S + 2, ST = T + 2; Dinic D; Input(D); int sum = 0; for (int i = 1; i <= T; ++i) { //建立与超级源汇点ss、st的边(别漏了源汇点!) if (Dif[i] > 0) { D.AddEdge(SS, i, Dif[i]); sum += Dif[i]; } if (Dif[i] < 0) D.AddEdge(i, ST, -Dif[i]); } int ans=D.MaxFlow(SS, ST); D.AddEdge(T, S, INF); ans += D.MaxFlow(SS, ST); if (ans != sum) { puts("impossible"); } else { printf("%d\n", D.G[T].rbegin()->f); } } return 0;}
阅读全文
0 0
- [刷题]HDU3157
- HDU3157 Crazy Circuits
- hdu3157 有源汇上下界最小流
- 刷题
- 刷题
- 刷题
- 刷题
- 刷题
- 刷题。。。
- 刷题
- 刷题
- 刷题
- 刷题
- 刷题
- 刷题
- 刷题
- 刷题!刷题!刷题网!!!
- POJ刷题
- 网站爬取
- yii2.0报的js冲突的错
- C语言:(新)四则计算器(支持括号和次方运算)
- ACM训练半周总结—10月26
- 内存泄漏
- [刷题]HDU3157
- TensorFlow 全连接网络实现
- CentOS 7搭建VPN虚拟局域网服务器
- Priority Queues
- 中介者模式学习和思考
- HTML插入图片存储路径问题
- C++中友元及继承
- Docker的安装
- golang基础-结构体、结构体链表前后插入、节点添加删除