zoukankan      html  css  js  c++  java
  • 平面图最小割 对偶图

    平面图最小割 对偶图:

    平面图G的性质:

    (1)满足n个点,m条边,f个面 f = m - n + 2;

    (2)存在与其对应的对偶图G*;

    对偶图:将原图中每个面变成一个点,外边界的无限大的面看成一个点,后连线即成对偶图;

    G的面数等于G*的点数,边数相等;

    详解请看 最大最小定理(平面图最小割 对偶图)周冬

    对于平面图的最大流(最小割)只需转化为对偶图,直接跑最短路即可;

    ps:觉得建图是最复杂的,各种RE(边数就是原来的边数,只是点数变成了原来的面数,,不注意就RE了);还有现在行数列数都变成减了1;原来的横线现在也变成了竖线;耐心点..一个debug的方法就是在ins插入边时输出,这样觉得挺好;

    对偶图裸题:

    hdu 3870 Catch the Theves

    // 296MS    12452K
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<stdlib.h>
    #include<time.h>
    #include<stack>
    #include<set>
    using namespace std;
    #define rep0(i,l,r) for(int i = (l);i < (r);i++)
    #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
    #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
    #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
    #define MS0(a) memset(a,0,sizeof(a))
    #define MS1(a) memset(a,-1,sizeof(a))
    #define inf 0x3f3f3f3f
    typedef __int64 ll;
    template<typename T>
    void read1(T &m)
    {
        T x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        m = x*f;
    }
    template<typename T>
    void read2(T &a,T &b){read1(a);read1(b);}
    template<typename T>
    void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
    template<typename T>
    void out(T a)
    {
        if(a>9) out(a/10);
        putchar(a%10+'0');
    }
    const int M = 404*404*2;
    int head[M<<1],tot;
    struct Edge{
        int to,w,Next;
        Edge(){}
        Edge(int to,int w,int nx):to(to),w(w),Next(nx){}
    }e[M<<1];
    inline void ins(int u,int v,int w)
    {
        e[tot] = Edge{v,w,head[u]};
        head[u] = tot++;
    }
    typedef pair<int,int> PII;
    #define MK make_pair
    #define A first
    #define B second
    priority_queue<PII,vector<PII>,greater<PII> > Q;
    bool vs[160016];
    int dist[M];
    ll Djistra(int s,int t)
    {
        while(!Q.empty()) Q.pop();
        fill(vs,vs+t+1,false);
        fill(dist,dist+t+1,inf);
        dist[s] = 0;
        Q.push(MK(0,s));
        while(!Q.empty()){
            PII tmp = Q.top();Q.pop();
            int u = tmp.B;
            if(vs[u]) continue;
            vs[u] = true;
            if(u == t) return dist[t];
            for(int id = head[u];~id;id = e[id].Next){
                int v = e[id].to,cost = e[id].w;
                if(dist[v] > dist[u] + cost){
                    dist[v] = dist[u] + cost;
                    Q.push(MK(dist[v],v));
                }
            }
        }
    }
    int main()
    {
        int n,T,kase = 1;
        read1(T);
        while(T--){
            read1(n);
            int s = 0, t = (n-1)*(n-1)+1;
            int u,v1,v2,x;
            MS1(head);tot = 0;
            rep0(i,0,n-1){ // n-1行特殊,只要加竖线即可;
                rep0(j,1,n){//注意j一定要从1开始;
                    read1(x);
                    u = i*(n-1)+j;//一般情况只需要找到当前节点的上面v1和左边v2
                    v1 = (i-1)*(n-1)+j;
                    v2 =  i*(n-1)+j-1;
                    if(i == 0) v1 = s;
                    if(j == 1) v2 = t;
                    ins(u,v1,x);ins(v1,u,x);
                    ins(u,v2,x);ins(v2,u,x);
                }
                read1(x);
                u = i*(n-1)+n-1;
                ins(u,s,x);ins(s,u,x);
            }
            rep0(j,1,n){
                read1(x);
                u = (n-2)*(n-1)+j;
                ins(u,t,x);ins(t,u,x);
            }
            read1(x);
            out(Djistra(s,t));
            puts("");
        }
        return 0;
    }
    View Code

    【bzoj】1001: [BeiJing2006]狼抓兔子

    前面使用优化的Dinic算法,用了1984ms,不是Dinic太慢(这还是较快的网络流算法了) 这道题原本就需要模型转化,变成最短路使用Djistra+优先队列 348ms;

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<stdlib.h>
    #include<time.h>
    #include<stack>
    #include<set>
    using namespace std;
    #define rep0(i,l,r) for(int i = (l);i < (r);i++)
    #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
    #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
    #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
    #define MS0(a) memset(a,0,sizeof(a))
    #define MS1(a) memset(a,-1,sizeof(a))
    #define inf 0x3f3f3f3f
    template<typename T>
    void read1(T &m)
    {
        T x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        m = x*f;
    }
    template<typename T>
    void read2(T &a,T &b){read1(a);read1(b);}
    template<typename T>
    void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
    template<typename T>
    void out(T a)
    {
        if(a>9) out(a/10);
        putchar(a%10+'0');
    }
    const int M = 1004*1004*2;
    int head[M*3],tot;
    struct Edge{
        int to,w,Next;
        Edge(){}
        Edge(int to,int w,int Next):to(to),w(w),Next(Next){}
    }e[M*3];
    inline void ins(int u,int v,int w)
    {
        //cout<<" ........... "<<u<<" "<<v<<" "<<w<<endl;
        e[tot] = Edge{v,w,head[u]};
        head[u] = tot++;
    }
    typedef pair<int,int> PII;
    #define MK make_pair
    #define A first
    #define B second
    priority_queue<PII,vector<PII>,greater<PII> > Q;
    bool vs[M];
    int dist[M];
    int Djistra(int s,int t)
    {
        while(!Q.empty()) Q.pop();
        fill(vs,vs+t+1,false);
        fill(dist,dist+t+1,inf);
        dist[s] = 0;
        Q.push(MK(0,s));
        while(!Q.empty()){
            PII tmp = Q.top();Q.pop();
            int u = tmp.B;
            if(vs[u]) continue;
            vs[u] = true;
            if(u == t) return dist[t];
            for(int id = head[u];~id;id = e[id].Next){
                int v = e[id].to,cost = e[id].w;
                if(dist[v] > dist[u] + cost){
                    dist[v] = dist[u] + cost;
                    Q.push(MK(dist[v],v));
                }
            }
        }
    }
    int main()
    {
        int n,m,x;
        read2(n,m);
        int s = 0,t = (n-1)*(m-1)*2+1;
        if(n == 1 || m == 1){//坑点不能建对偶图,没意思
            int ans = inf;
            if(n != 1) swap(n,m);
            rep0(i,1,m){
                read1(x);
                ans = min(ans,x);
            }
            return out(ans == inf?0:ans),0;
        }
        fill(head,head+t+1,-1);tot = 0;
        rep0(i,0,n){
            rep0(j,1,m){
                read1(x);
                int u = (i*(m-1)+j)*2,
                v = ((i-1)*(m-1)+j)*2-1;
                if(i == 0) v = s;
                if(i == n-1) u =u-2*(m-1)-1, v = t;
                ins(u,v,x);ins(v,u,x);
            }
        }
        rep0(i,0,n-1){
            rep1(j,1,m){
                read1(x);
                int u = (i*(m-1)+j)*2-1,
                v = u-1;
                if(j == 1) v = t;
                if(j == m) u -= 1,v = s;
                ins(u,v,x);ins(v,u,x);
            }
        }
        rep0(i,0,n-1){
            rep0(j,1,m){
                read1(x);
                int u = (i*(m-1)+j)*2,
                v = u - 1;
                ins(u,v,x);ins(v,u,x);
            }
        }
        out(Djistra(s,t));
        return 0;
    }
    View Code
  • 相关阅读:
    java多线程--定时器Timer的使用
    java多线程--线程池的使用
    java多线程--多线程基础小结
    java基础--java.util.Date类型小结
    onClickRow 事件
    C#里的SubString和Convert.ToDateTime
    jquery+easyui开发、培训文档
    Jquery函数大全
    前端最全的 API 集锦
    17个CSS知识点整理
  • 原文地址:https://www.cnblogs.com/hxer/p/5189510.html
Copyright © 2011-2022 走看看