zoukankan      html  css  js  c++  java
  • 【BZOJ1001】狼抓兔子(BJOI2006)-平面图最小割转最短路

    测试地址:狼抓兔子
    做法:本题需要用到平面图最小割转最短路。
    注意到题目中要求一个平面图的最小割,然而这个图点数太多,我们不可能直接用网络流求解,但是我们注意到,如果在平面图中每两个相邻区域之间连双向边(我们把右、上边界和左、下边界看做两个不相邻的平面区域),边的长度为这两个区域的公共边的权值,这时候我们发现,每一个割都对应了一条从右、上边界到左、下边界的路径,因此按这样建图之后跑最短路即可,因为SPFA会被卡,因此用Dijkstra实现即可,时间复杂度为O(nmlog(nm))。注意特判n=1m=1的情况。
    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #define inf 1000000000
    using namespace std;
    int n,m,x,first[2000010]={0},tot=0,t,dis[2000010];
    struct edge {int v,d,next;} e[12000010];
    bool vis[2000010]={0};
    struct point
    {
        int val,id;
        bool operator < (point a) const
        {
            return val>a.val;
        }
    };
    priority_queue <point> Q;
    
    void insert(int a,int b,int d)
    {
        e[++tot].v=b;
        e[tot].d=d;
        e[tot].next=first[a];
        first[a]=tot;
    }
    
    void dijkstra()
    {
        point now,nxt;
        now.val=0,now.id=0;
        vis[0]=1,dis[0]=0;
        for(int i=1;i<=t;i++) dis[i]=inf;
        for(int i=first[0];i;i=e[i].next)
        {
            nxt.val=e[i].d;
            nxt.id=e[i].v;
            dis[e[i].v]=e[i].d;
            Q.push(nxt);
        }
        while(!Q.empty())
        {
            now=Q.top();
            while(vis[now.id]&&!Q.empty()) Q.pop(),now=Q.top();
            if (Q.empty()) break;
            vis[now.id]=1;
            for(int i=first[now.id];i;i=e[i].next)
                if (dis[e[i].v]>dis[now.id]+e[i].d)
                {
                    dis[e[i].v]=dis[now.id]+e[i].d;
                    nxt.id=e[i].v;
                    nxt.val=dis[e[i].v];
                    Q.push(nxt);
                }
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
    
        t=2*(n-1)*(m-1)+1;
        int minx=inf;
        for(int i=1;i<m;i++)
        {
            scanf("%d",&x);
            minx=min(x,minx);
            insert(0,i,x);
        }
        for(int i=1;i<n-1;i++)
        {
            int s=(2*i-1)*(m-1);
            for(int j=1;j<m;j++)
            {
                scanf("%d",&x);
                minx=min(minx,x);
                insert(s+j,s+j+m-1,x);
                insert(s+j+m-1,s+j,x);
            }
        }
        for(int i=1;i<m;i++)
        {
            scanf("%d",&x);
            minx=min(minx,x);
            insert((2*n-3)*(m-1)+i,t,x);
        }
        for(int i=1;i<n;i++)
        {
            int s=(2*i-1)*(m-1);
            scanf("%d",&x);
            minx=min(minx,x);
            insert(s+1,t,x);
            for(int j=2;j<m;j++)
            {
                scanf("%d",&x);
                minx=min(minx,x);
                insert(s+j,s+j-m,x);
                insert(s+j-m,s+j,x);
            }
            scanf("%d",&x);
            minx=min(minx,x);
            insert(0,s,x);
        }
        for(int i=1;i<n;i++)
        {
            int s=(2*i-1)*(m-1);
            for(int j=1;j<m;j++)
            {
                scanf("%d",&x);
                minx=min(minx,x);
                insert(s+j,s+j-m+1,x);
                insert(s+j-m+1,s+j,x);
            }
        }
    
        if (n==1||m==1) {printf("%d",minx);return 0;}
        dijkstra();
        printf("%d",dis[t]);
    
        return 0;
    }
  • 相关阅读:
    pyecharts包学习笔记
    敏捷测试关键成功因素
    JMeter—常见问题(十四)
    性能测试面试题
    python-Tkinter整理总结
    JMeter—系统性能分析思路(十三)
    JMeter—监听器(十二)
    JMeter—断言(十一)
    yii2.0 的数据的 增
    Windows下安装 使用coreseek
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793553.html
Copyright © 2011-2022 走看看