zoukankan      html  css  js  c++  java
  • 【BZOJ】2007: [Noi2010]海拔(平面图转对偶图)

    题目

    传送门:QWQ

    分析

    左上角是0,右下角是1。那么大概整张图是由0 1构成的。

    那么我们要找到0和1的分界线,值就是最小割。

    然后变成求原图最小割。

    考虑到此题是平面图,那么就转成对偶图跑最短路。

    完了。

    总结:以后看到数据在$ nlog(n) $范围内的题,给的图是方格图,给的边还方方正正,那么多半是平面图转对偶图。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=510*510;
    vector<int> G[maxn];
    struct Edge{ int u,v,dis; };
    vector<Edge> edges;
    struct HeapNode{
        int x,dis;
        bool operator <(const HeapNode& a) const{ return dis>a.dis; }
    };
    void link(int u,int v,int dis){
        edges.push_back((Edge){u,v,dis}); //edges.push_back((Edge){v,u,dis});
        int m=edges.size(); G[u].push_back(m-1);
    }
    int d[maxn],vis[maxn];
    priority_queue<HeapNode> que; 
    int dijkstra(int s,int t){
        memset(d,127,sizeof(d));
        d[s]=0; que.push((HeapNode){s,0}); //vis[s]=1;
        while(!que.empty()){
            HeapNode x=que.top(); que.pop();
            if(vis[x.x]) continue; vis[x.x]=1;
            int u=x.x;
            for(int i=0;i<G[u].size();i++){
                Edge& e=edges[G[u][i]];
                if(d[e.v]>d[u]+e.dis){
                    d[e.v]=d[u]+e.dis;
                    que.push((HeapNode){e.v,d[e.v]}); 
                }
            }
        }
        return d[t];
    }
    int num[505][505];
    int main(){
        int n,x;scanf("%d",&n);
        int    s = 0 , t = n * n + 1;
        for(int i = 1 ; i <= n ; i ++ )
            num[0][i] = num[i][n + 1] = s , num[i][0] = num[n + 1][i] = t;
        for(int i=1; i <= n ; i ++ )
            for(int j = 1 ; j <= n ; j ++ )
                num[i][j] = n * (i - 1) + j;
        for(int i=0;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&x),link(num[i][j] , num[i+1][j] , x);
        for(int i=1;i<=n;i++) for(int j=0;j<=n;j++) scanf("%d",&x),link(num[i][j+1] , num[i][j] , x);
        for(int i=0;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&x),link(num[i+1][j] , num[i][j] , x);
        for(int i=1;i<=n;i++) for(int j=0;j<=n;j++) scanf("%d",&x),link(num[i][j] , num[i][j+1] , x);
        printf("%d
    ",dijkstra(s,t));
        return 0;
    }
  • 相关阅读:
    【ALearning】第三章 Android基本常见控件
    【问题汇总】ListView的FooterView设置可见性的问题
    shell重定向调试信息
    Android提供的系统服务之--TelephonyManager(电话管理器)
    工作一年的总结
    【甘道夫】HBase基本数据操作的详细说明【完整版,精绝】
    未定义标识符_ConnectionPtr
    POJ 1329 三角外接圆
    IOS开发-加载本地音乐
    SQL Server 性能优化3 该指数(Index)保养
  • 原文地址:https://www.cnblogs.com/noblex/p/9161791.html
Copyright © 2011-2022 走看看