UVa 11248 Frequency Hopping(最小割入门)
2013-04-12 15:48
302 查看
题意:
给定一个有向网络,每条边均有一个容量。问是否存在一个点 1 到点 N 流量为 C 的流。如果不存在,是否可以恰好修改一条弧的容量,使得存在这样的流。
思路:
1. 首先求最大流,若最大流大于 C ,则直接输出即可。如果不大于 C 则需要修改最小割里面的弧;
2. 关于如何求最小割:求出最大流之后,S->T 已经不存在一条增广路径了。但是仍然按照增广路径的走法,遍历出分别包含 S T 的点集;
3. 关于上面可以反向来理解:如果点集 T 中有一个点位于点集 S,则增加这两点之间的流量就能继续找到一条增广路径,这显然是违背最大流的;
4. 修改割里面的弧,每次求出相应的最大流即可。中间用到 2 点优化,一是在以前的最大流基础上增广,二是每次求最大流只需要求是否满足需求即可;
给定一个有向网络,每条边均有一个容量。问是否存在一个点 1 到点 N 流量为 C 的流。如果不存在,是否可以恰好修改一条弧的容量,使得存在这样的流。
思路:
1. 首先求最大流,若最大流大于 C ,则直接输出即可。如果不大于 C 则需要修改最小割里面的弧;
2. 关于如何求最小割:求出最大流之后,S->T 已经不存在一条增广路径了。但是仍然按照增广路径的走法,遍历出分别包含 S T 的点集;
3. 关于上面可以反向来理解:如果点集 T 中有一个点位于点集 S,则增加这两点之间的流量就能继续找到一条增广路径,这显然是违背最大流的;
4. 修改割里面的弧,每次求出相应的最大流即可。中间用到 2 点优化,一是在以前的最大流基础上增广,二是每次求最大流只需要求是否满足需求即可;
#include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; const int MAXN = 110; const int INFS = 0x3FFFFFFF; struct edge { int from, to, cap, flow; edge(int _from, int _to, int _cap, int _flow) : from(_from), to(_to), cap(_cap), flow(_flow) {} bool operator < (const edge& rhs) const { if (from == rhs.from) return to < rhs.to; return from < rhs.from; } }; class ISAP { public: void clearall(int n) { this->n = n; for (int i = 0; i < n; i++) G[i].clear(); edges.clear(); } bool bfs() { queue<int> Q; d[t] = 0; memset(vis, false, sizeof(vis)); vis[t] = true; Q.push(t); while (!Q.empty()) { int x = Q.front(); Q.pop(); for (int i = 0; i < G[x].size(); i++) { edge& e = edges[G[x][i]^1]; if (!vis[e.from] && e.cap > e.flow) { vis[e.from] = true; d[e.from] = d[x] + 1; Q.push(e.from); } } } return vis[s]; } void addedge(int u, int v, int cap) { edges.push_back(edge(u, v, cap, 0)); edges.push_back(edge(v, u, 0, 0)); G[u].push_back(edges.size() - 2); G[v].push_back(edges.size() - 1); } int augment() { int x = t, a = INFS; while (x != s) { edge& e = edges[p[x]]; a = min(a, e.cap - e.flow); x = e.from; } x = t; while (x != s) { edges[p[x]].flow += a; edges[p[x]^1].flow -= a; x = edges[p[x]].from; } return a; } int maxflow(int s, int t, int need) { this->s = s, this->t = t; bfs(); memset(gap, 0, sizeof(gap)); for (int i = 0; i < n; i++) cur[i] = 0, gap[d[i]] += 1; int x = s, flow = 0; while (d[s] < n) { if (x == t) { flow += augment(); if (flow >= need) return flow; x = s; } bool flag = false; for (int i = cur[x]; i < G[x].size(); i++) { edge& e = edges[G[x][i]]; if (e.cap > e.flow && d[x] == d[e.to] + 1) { flag = true; cur[x] = i; p[e.to] = G[x][i]; x = e.to; break; } } if (!flag) { int m = n - 1; for (int i = 0; i < G[x].size(); i++) { edge& e = edges[G[x][i]]; if (e.cap > e.flow) m = min(m, d[e.to]); } if (--gap[d[x]] == 0) break; gap[d[x] = m+1] += 1; cur[x] = 0; if (x != s) x = edges[p[x]].from; } } return flow; } void mincut(vector<int>& cut) { bfs(); for (int i = 0; i < edges.size(); i++) { edge& e = edges[i]; if (!vis[e.from] && vis[e.to] && e.cap > 0) cut.push_back(i); } } void reduce() { for (int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow; } void clearflow() { for (int i = 0; i < edges.size(); i++) edges[i].flow = 0; } public: int n, s, t; vector<edge> edges; vector<int> G[MAXN]; int p[MAXN], d[MAXN], cur[MAXN], gap[MAXN]; bool vis[MAXN]; }; ISAP sap; int main() { int n, e, c, cases = 0; while (scanf("%d%d%d", &n, &e, &c) && n) { sap.clearall(n); while (e--) { int u, v, fp; scanf("%d%d%d", &u, &v, &fp); sap.addedge(u - 1, v - 1, fp); } int flow = sap.maxflow(0, n - 1, INFS); printf("Case %d: ", ++cases); if (flow >= c) { printf("possible\n"); } else { vector<int> cut; vector<edge> ans; sap.mincut(cut); sap.reduce(); for (int i = 0; i < cut.size(); i++) { edge& e = sap.edges[cut[i]]; sap.clearflow(); e.cap = c; if (flow + sap.maxflow(0, n - 1, c - flow) >= c) ans.push_back(e); e.cap = 0; } if(ans.empty()) printf("not possible\n"); else { sort(ans.begin(), ans.end()); printf("possible option:(%d,%d)", ans[0].from + 1, ans[0].to + 1); for(int i = 1; i < ans.size(); i++) printf(",(%d,%d)", ans[i].from + 1, ans[i].to + 1); printf("\n"); } } } return 0; }
相关文章推荐
- uva 11248 - Frequency Hopping 最大流最小割入门题 求割集模板
- 【最小割】 UVA 11248 Frequency Hopping
- UVa 11248 - Frequency Hopping - 最大流 - 最小割
- uva 1395 苗条的生成树(最小生成树入门)
- uva 11248 最小割
- UVA 11248 Frequency Hopping(最大流、最小割)
- UVA-11248 Frequency Hopping (最大流+最小割)
- Frequency Hopping UVA - 11248 网络流简单容量修改/最小割
- uva 11248 最小割
- UVA 11248 Frequency Hopping (最大流+最小割)
- UVA 11248 Frequency Hopping 最小割
- UVa11248 Frequency Hopping(最大流+最小割)
- UVA 11248 网络扩容 最小割
- UVa 11733 Airports(变形的最小生成树)
- 最短路+字典序最小+输出路径(Ideal Path,UVA 1599)
- 最小生成树(苗条生成树 uva 1395)
- 网络流(最大流,最小割)基础入门详解
- 最小倍数的最小和(Uva 10791)
- uva 11419 SAM I AM 求出二分图的最小点覆盖集
- UVALive-3487 Duopoly(最小割)