zoukankan      html  css  js  c++  java
  • 平面图中最小割向最短路的转化

    周冬的《两极相通——浅析最大最小定理在信息学竞赛中的应用》把方法讲的很详细了。

    几点:

    1、把平面图G*中每一个面抽象成对偶图G*中的点。

    2、平面图包含f个面,设边e分割fi, fj,则连边(fi, fj)。

    3、关于如何区分源点和汇点。可以先连接s和t,得到一个附加面。如下图s->4->7->t->s,s*放到附加面中,t*放到无边界的面中,加以区分。

    4、建好图后要把(s*, t*)这条边删掉。

    5、G的面数等于G*的点数,G*的点数等于G的面数

    6、G与G*边数相同 G*中的环对应G中的割一一对应

    如图:

    hdu 3780

    题意是求最小割。直接套网络流模板会TLE。转换成最短路模型然后用dijkstra求解就行,不过dijkstra要优先队列优化。

    得到的最短路模型中,点数最多为(n - 1)*n*2 - n*n + 2,边数最多为(n - 1)*n*2*2,注意别MLE;

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%lld\n", x)
    #define Read()  freopen("data.in", "r", stdin)
    #define Write() freopen("data.out", "w", stdout);
    
    typedef long long LL;
    const double eps = 1e-6;
    const double PI = acos(-1.0);
    const int inf = 0x1F1F1F1F;
    
    using namespace std;
    
    const int N = 410;
    
    int mp[N][N];
    
    class node {
    public:
        int to;
        int val;
        int next;
    }g[N*N<<2];
    
    class pnode {
    public:
        int num;
        int len;
        pnode() {};
        pnode(int a, int b) : num(a), len(b) {}
        bool operator < (const pnode p) const {
            return this->len > p.len;
        }
    };
    
    priority_queue<pnode> q;
    
    int head[N*N + 10], t;
    int dis[N*N + 10];
    bool vis[N*N + 10];
    
    int S, T, n;
    
    void init() {
        memset(head, -1, sizeof(head));
        t = 0;
    }
    
    void add(int u, int v, int c) {
        g[t].to = v; g[t].val = c; g[t].next = head[u]; head[u] = t++;
        g[t].to = u; g[t].val = c; g[t].next = head[v]; head[v] = t++;
    }
    
    int dijkstra(int s, int t) {
        while(!q.empty())   q.pop();
        q.push(pnode(s, 0));
    
        int i, v;
        pnode u;
    
        for(i = 0; i <= t; ++i) {
            dis[i] = inf;
            vis[i] = false;
        }
        dis[0] = 0;
    
        while(!q.empty()) {
            u = q.top(); q.pop();
            if(u.len != dis[u.num]) continue;
            if(vis[u.num])  continue;
            vis[u.num] = true;
    
            for(i = head[u.num]; i != -1; i = g[i].next) {
                v = g[i].to;
                if(dis[v] > u.len + g[i].val) {
                    dis[v] = u.len + g[i].val;
                    q.push(pnode(v, dis[v]));
                }
            }
        }
        return dis[t];
    }
    
    int main() {
        //Read();
    
        int TT, n, i, j, u, S, T;
        scanf("%d", &TT);
        while(TT--) {
            scanf("%d", &n);
            for(i = 1; i <= n; ++i) {
                for(j = 1; j <= n; ++j) {
                    scanf("%d", &mp[i][j]);
                }
            }
            init();
            S = 0; T = (n - 1)*(n - 1) + 1;
            for(i = 1; i <= n - 1; ++i) {
                for(j = 1; j <= n - 1; ++j) {
                    u = (i - 1)*(n - 1) + j;
                    if(i == 1)  add(S, u, mp[i][j]);
                    if(j == 1)  add(u, T, mp[i][j]);
                    if(i == n - 1)  add(u, T, mp[i + 1][j]);
                    if(j == n - 1)  add(S, u, mp[i][j + 1]);
                    if(i < n - 1)   add(u, u + n - 1, mp[i + 1][j]);
                    if(j < n - 1)   add(u, u + 1, mp[i][j + 1]);
                }
            }
            printf("%d\n", dijkstra(S, T));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    eclipse不提示
    怎么在eclipse中安装properties插件
    表单验证之validform.js使用方法
    Activiti Service介绍
    activiti插件安装-离线安装
    三分钟明白 Activiti工作流 -- java运用
    Eclipse中快捷键Ctrl + Alt + 向上箭头 或者 Ctrl + Alt + 向下箭头与Windows冲突
    Eclipse 从git导入maven多模块项目
    封印
    教主的花园
  • 原文地址:https://www.cnblogs.com/vongang/p/3111972.html
Copyright © 2011-2022 走看看