UVA-10480 Sabotage (minimum cut, cutting edge scheme)

Topic links: UVA-10480 Sabotage

The meaning of problems

FIG even give a side (undirected edges) and cut the cost of each edge, to cut off some of the edges so that the node 1 and the node 2 is not connected, the program seeking minimum cost cut.


Thinking

On the picture to the source node 1, node 2 is the sink node, the edge cost network flow capacity is established, the minimum is the minimum cost cut.

Provided cutting edge into the stream of the network nodes S $ $ $ T $ and two sets. Residual network after the Ford-Fulkerson method of seeking maximum flow, starting from the source dfs, each pass residual capacity is greater than $ 0 $ sides, to find all the nodes in the set $ S $. All sides $ (u, v) $, if $ u \ in S, v \ in T $, then $ (u, v) $ is cutting edge.


Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using std::queue;
const int INF = 0x3f3f3f3f, N = 60, M = 1100;
int head[N], d[N];
int s, t, tot, maxflow;
bool vis[N];
struct Edge
{
    int to, cap, nex;
} edge[M];
queue<int> q;
void add(int x, int y, int z) {
    edge[++tot].to = y, edge[tot].cap = z, edge[tot].nex = head[x], head[x] = tot;
}
bool bfs() {
    memset(d, 0, sizeof(d));
    while (q.size()) q.pop();
    q.push(s); d[s] = 1;
    while (q.size()) {
        int x = q.front(); q.pop();
        for (int i = head[x]; i; i = edge[i].nex) {
            int v = edge[i].to;
            if (edge[i].cap && !d[v]) {
                q.push(v);
                d[v] = d[x] + 1;
                if (v == t) return true;
            }
        }
    }
    return false;
}
int dinic(int x, int flow) {
    if (x == t) return flow;
    int rest = flow, k;
    for (int i = head[x]; i && rest; i = edge[i].nex) {
        int v = edge[i].to;
        if (edge[i].cap && d[v] == d[x] + 1) {
            k = dinic(v, std::min(rest, edge[i].cap));
            if (!k) d[v] = 0;
            edge[i].cap -= k;
            edge[i^1].cap += k;
            rest -= k;
        }
    }
    return flow - rest;
}
void init() {
    tot = 1, maxflow = 0;
    s = 1, t = 2;
    memset(head, 0, sizeof(head));
    memset(vis, false, sizeof(vis));
}
void dfs(int u) {
  vis[u] = true;
  for (int i = head[u]; i; i = edge[i].nex) {
    int v = edge[i].to;
    if (!vis[v] && edge[i].cap) dfs(v);
  }
}

int main() {
    int n, m;
    while (~scanf("%d %d", &n, &m) && (n || m)) {
        init();
        for (int i = 0, u, v, z; i < m; i++) {
            scanf("%d %d %d", &u, &v, &z);
            add(u, v, z);
            add(v, u, z);
        }
        while (bfs()) maxflow += dinic(s, INF);
        dfs(s);
        for (int i = 1; i <= n; i++) {
            if (vis[i]) {
                for (int j = head[i]; j; j = edge[j].nex) {
                    if (!vis[edge[j].to]) printf("%d %d\n", i, edge[j].to);
                }
            }
        }
        puts("");
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/kangkang-/p/11333032.html