zoukankan      html  css  js  c++  java
  • HDU

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3035

    题意

    给个图,求把s和t分开的最小割。

    分析

    实际顶点和边非常多,不能用最大流来求解。这道题要用平面图求最小割的方法:

    把面变成顶点,对每两个面相邻的边作一条新边。然后求最短路就是最小割了。

    另外,外平面分成两个点,分别是源点和汇点,源点连左下的边,汇点连右上的边,这样跑出来才是正确的。

    建图参考自:https://blog.csdn.net/accelerator_/article/details/40957675

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <queue>
    using namespace std;
     
    const int MAXNODE = 1000005;
    const int MAXEDGE = 3 * MAXNODE;
     
    typedef int Type;
    const Type INF = 0x3f3f3f3f;
     
    struct Edge {
        int u, v;
        Type dist;
        Edge() {}
        Edge(int u, int v, Type dist) {
            this->u = u;
            this->v = v;
            this->dist = dist;
        }
    };
     
    struct HeapNode {
        Type d;
        int u;
        HeapNode() {}
        HeapNode(Type d, int u) {
            this->d = d;
            this->u = u;
        }
        bool operator < (const HeapNode& c) const {
            return d > c.d;
        }
    };
     
    struct Dijkstra {
        int n, m;
        Edge edges[MAXEDGE];
        int first[MAXNODE];
        int next[MAXEDGE];
        bool done[MAXNODE];
        Type d[MAXNODE];
     
        void init(int n) {
            this->n = n;
            memset(first, -1, sizeof(first));
            m = 0;
        }
     
        void add_Edge(int u, int v, Type dist) {
            edges[m] = Edge(u, v, dist);
            next[m] = first[u];
            first[u] = m++;
        }
     
        Type dijkstra(int s, int t) {
            priority_queue<HeapNode> Q;
            for (int i = 0; i < n; i++) d[i] = INF;
            d[s] = 0;
            memset(done, false, sizeof(done));
            Q.push(HeapNode(0, s));
            while (!Q.empty()) {
                HeapNode x = Q.top(); Q.pop();
                int u = x.u;
                if (done[u]) continue;
                done[u] = true;
                for (int i = first[u]; i != -1; i = next[i]) {
                    Edge& e = edges[i];
                    if (d[e.v] > d[u] + e.dist) {
                        d[e.v] = d[u] + e.dist;
                        Q.push(HeapNode(d[e.v], e.v));
                    }
                }
            }
            return d[t];
        }
    } gao;
     
    typedef long long ll;
     
    int n, m;
     
    int main() {
        while (~scanf("%d%d", &n, &m)) {
            int u, v, w;
            gao.init(n * m * 4 + 2);
            int s = n * m * 4, t = n * m * 4 + 1;
            for (int i = 0; i < (n + 1); i++) {
                for (int j = 0; j < m; j++) {
                    scanf("%d", &w);
                    u = (i - 1) * m + j + n * m;
                    v = i * m + j;
                    if (i == 0) u = t;
                    if (i == n) v = s;
                    gao.add_Edge(u, v, w);
                    gao.add_Edge(v, u, w);
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < (m + 1); j++) {
                    scanf("%d", &w);
                    u = n * m * 3 + i * m + j - 1;
                    v = n * m * 2 + i * m + j;
                    if (j == 0) u = s;
                    if (j == m) v = t;
                    gao.add_Edge(u, v, w);
                    gao.add_Edge(v, u, w);
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    scanf("%d", &w);
                    u = i * m + j;
                    v = n * m * 2 + i * m + j;
                    gao.add_Edge(u, v, w);
                    gao.add_Edge(v, u, w);
                    scanf("%d", &w);
                    v += n * m;
                    gao.add_Edge(u, v, w);
                    gao.add_Edge(v, u, w);
                }
                for (int j = 0; j < m; j++) {
                    scanf("%d", &w);
                    u = n * m + i * m + j;
                    v = n * m * 2 + i * m + j;
                    gao.add_Edge(u, v, w);
                    gao.add_Edge(v, u, w);
                    scanf("%d", &w);
                    v += n * m;
                    gao.add_Edge(u, v, w);
                    gao.add_Edge(v, u, w);
                }
            }
            printf("%d
    ", gao.dijkstra(s, t));
        }
        return 0;
    }
  • 相关阅读:
    C语言第三次博客作业---单层循环结构
    C语言第二次博客作业---分支结构
    C语言第一次博客作业
    第0次作业
    第09组 Beta冲刺(1/5)
    第09组 Alpha事后诸葛亮
    第09组 Alpha冲刺(6/6)
    第09组 Alpha冲刺(5/6)
    第09组 Alpha冲刺(4/6)
    第09组 Alpha冲刺(3/6)
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9773497.html
Copyright © 2011-2022 走看看