Ultraviolet A-11248 Frequency Hopping (network stream + cut)
There are N vertices, M directed edges, and each edge has a corresponding capacity. Now you are required to ship from Point 1 to point N. The shipping volume is C.
If it can be shipped, output possible
If it cannot be shipped, check whether it can increase only one arc to make the shipping successful. If so, output all the arcs that can be increased.
Otherwise
Solution: first run the largest stream. If the maximum stream is greater than or equal to C, no arc exists.
If not, perform an arc.
Which arcs can be expanded. The answer is the cut edge capacity, because the minimum cut = the maximum flow
First, we need to find all the cut edges. How can we find the cut edges? If it is a dinic algorithm, find the edges with vis [u] = true and vis [v] = false and the edge capacity is greater than 0. These edges are cut edges.
Then, we need to expand the size of each part of the cut side to the capacity of C, and then run the maximum stream on the residual network.
Another problem is how to find the residual network. You only need to subtract the capacity of all edges from the traffic to become the residual network.
#include
#include
#include #include
#include
using namespace std;#define N 1010#define INF 0x3f3f3f3fstruct Edge{ int from, to, cap, flow; Edge() {} Edge(int from, int to, int cap, int flow) : from(from), to(to), cap(cap), flow(flow) {}};struct Dinic{ int n, m, s, t; vector
edges; vector
G[N]; bool vis[N]; int d[N], cur[N]; void init(int n) { this->n = n; for (int i = 0; i <= n; i++) { G[i].clear(); } edges.clear(); } void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); int m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } bool BFS() { memset(vis, 0, sizeof(vis)); queue
Q; Q.push(s); vis[s] = 1; d[s] = 0; while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (!vis[e.to] && e.cap > e.flow) { vis[e.to] = true; d[e.to] = d[u] + 1; Q.push(e.to); } } } return vis[t]; } int DFS(int x, int a) { if (x == t || a == 0) return a; int flow = 0, f; for (int i = cur[x]; i < G[x].size(); i++) { Edge &e = edges[G[x][i]]; if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) { e.flow += f; edges[G[x][i] ^ 1].flow -= f; flow += f; a -= f; if (a == 0) break; } } return flow; } int Maxflow(int s, int t) { this->s = s; this->t = t; int flow = 0; while (BFS()) { memset(cur, 0, sizeof(cur)); flow += DFS(s, INF); } return flow; } void clear() { for (int i = 0; i < edges.size(); i++) edges[i].flow = 0; } void remmant() { for (int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow; } vector
MinCut() { vector
tmp; for (int i = 0; i < edges.size(); i++) if (vis[edges[i].from] && !vis[edges[i].to] && edges[i].cap > 0) tmp.push_back(i); return tmp; }};Dinic dinic;#define M 10010int n, m, c;int cas = 1;struct Cut{ int u, v; bool operator <(const Cut &a) const { if (u == a.u) return v < a.v; return u < a.u; }}cut[M];int cmp(const Cut &a, const Cut &b) { if (a.u == b.u) return a.v < b.v; return a.u < b.u;}void solve() { dinic.init(n); int u, v, cost; for (int i = 0; i < m; i++) { scanf(%d%d%d, &u, &v, &cost); dinic.AddEdge(u, v, cost); } printf(Case %d: , cas++); int Maxflow = dinic.Maxflow(1, n); if (Maxflow >= c) printf(possible); else { int cnt = 0; vector
tmp = dinic.MinCut(); dinic.remmant(); for (int i = 0; i < tmp.size(); i++) { Edge &e = dinic.edges[tmp[i]]; dinic.clear(); e.cap = c; int ans = dinic.Maxflow(1,n); if (ans + Maxflow >= c) { cut[cnt].u = dinic.edges[tmp[i]].from; cut[cnt++].v = dinic.edges[tmp[i]].to; } e.cap = 0; } if (cnt == 0) printf(not possible); else { sort(cut, cut + cnt); printf(possible option:(%d,%d), cut[0].u, cut[0].v); for (int i = 1; i < cnt; i++) printf(,(%d,%d), cut[i].u, cut[i].v); printf(); } }}int main() { while (scanf(%d%d%d, &n, &m, &c) != EOF && n + m + c) solve(); return 0;}