HDU - 3870 Catch the Theves(最小割+对偶图==最短路)

来源:互联网 发布:java io流读取文件方式 编辑:程序博客网 时间:2024/05/16 11:17

题目大意:给出一张图,这张图的每条边都有相应的容量,现在问(1,1)到(N,M)的最小割是多少

解题思路:转成对偶图,就可以用最短路了

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;const int MAXNODE = 160010;const int MAXEDGE = MAXNODE * 4;const int INF = 0x3f3f3f3f;struct Edge{    int v, val, next;    Edge() {}    Edge(int v, int val, int next): v(v), val(val), next(next) {}}E[MAXEDGE];struct Node {    int v, val;    Node() {}    Node(int v, int val): v(v), val(val) {}    bool operator <(const Node &a) const {        return val > a.val;    }};int n, source, sink, tot;int d[MAXNODE], head[MAXNODE];bool vis[MAXNODE];void AddEdge(int u, int v, int cap) {    E[tot] = Edge(v, cap, head[u]);    head[u] = tot++;    u = u ^ v; v = u ^ v; u = u ^ v;    E[tot] = Edge(v, cap, head[u]);    head[u] = tot++;}void init() {    scanf("%d", &n);    memset(head, -1, sizeof(head));    tot = 0;    source = (n - 1) * (n - 1) + 1, sink = source + 1;    int val;    for (int i = 1; i <= n; i++) {        scanf("%d", &val);        if (i == 1) {            AddEdge(i, source, val);            AddEdge(i, sink, val);        } else if (i != n) {            AddEdge(i, sink, val);            AddEdge(i, i - 1, val);        }        else AddEdge(i - 1, sink, val);    }    for (int i = 1; i < n - 1; i++)  {        scanf("%d", &val);        AddEdge(i * (n - 1) + 1, source, val);        AddEdge(i * (n - 1) + 1, (n - 1) * (i - 1) + 1, val);        for (int j = 2; j < n; j++) {            scanf("%d", &val);            AddEdge(i * (n - 1) + j, i * (n - 1) + j - 1, val);            AddEdge(i * (n - 1) + j, (i - 1) * (n - 1) + j, val);        }        scanf("%d", &val);        AddEdge((i + 1) * (n - 1), sink, val);    }    for (int i = 1; i <= n; i++) {        scanf("%d", &val);        if (i != n) AddEdge((n - 1) * (n - 2) + i, source, val);    }}void Dijkstra() {    for (int i = 1; i <= sink; i++) {        d[i] = INF; vis[i] = false;    }    d[source] = 0;    priority_queue<Node> Q;    Q.push(Node(source, 0));    while (!Q.empty()) {        int u = Q.top().v; Q.pop();        if (vis[u]) continue;        vis[u] = true;        for (int i = head[u]; ~i; i = E[i].next) {            int v = E[i].v;            if (d[v] > d[u] + E[i].val) {                d[v] = d[u] + E[i].val;                Q.push(Node(v, d[v]));            }        }    }    printf("%d\n", d[sink]);}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();        Dijkstra();    }    return 0;}
0 0