码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ_1001_狼抓兔子(平面图求最小割+对偶图求最短路)

时间:2016-05-13 23:03:09      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

描述


http://www.lydsy.com/JudgeOnline/problem.php?id=1001

 

分析


平面图求最小割,转化成对偶图求最短路,经典.

 

注意:

1.优先队列是个大根堆.

2.Dijkstra可以带一个vis数组,也可以不带,因为一个点出来以后,它更新的的点和原本就在队列里的点都比它大,所以它不可能被更新得更小,之后这个点再出队时情况不比第一次更优,所以出队也不会有操作.

3.双向边,数组要开够(貌似不是第一次犯这个错误).

4.网上有人说m==1||n==1的情况可以不特判,在get函数中已经可以处理妥当,大丈夫.

 

 

技术分享
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
 
const int maxn=1000+10,oo=1<<27;
int n,m,cnt;
int d[maxn*maxn*2],head[maxn*maxn*4];
bool vis[maxn*maxn*2];
struct edge{
    int to,w,next;
    edge(){}
    edge(int a,int b,int c):to(a),w(b),next(c){}
    bool operator<(const edge &a) const { return a.w<w; }
}g[maxn*maxn*6];
void insert(int from,int to,int w){
    g[++cnt]=edge(to,w,head[from]); head[from]=cnt; 
    g[++cnt]=edge(from,w,head[to]); head[to]=cnt;
}
 
int get(int x,int y,int z){
    if(x<1||y>=m) return ((n-1)*(m-1)<<1)+1;
    if(x>=n||y<1) return 0;
    return (((x-1)*(m-1)+y-1)<<1)+z+1;
}
int Dijkstra(int s,int t){
    for(int i=0;i<=((n-1)*(m-1)<<1)+1;i++) d[i]=oo;
    d[s]=0;
    priority_queue <edge> q;
    q.push(edge(s,0,0));
    while(!q.empty()){
        edge e=q.top(); q.pop();
        int x=e.to;
        if(vis[x]) continue;
        vis[x]=true;
        for(int i=head[x];i;i=g[i].next){
            int y=g[i].to;
            if(d[y]>d[x]+g[i].w){
                d[y]=d[x]+g[i].w;
                q.push(edge(y,d[y],0));
            }
        }
    }
    return d[t];
}
 
void init(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<m;j++){
            int a; scanf("%d",&a);
            insert(get(i,j,1),get(i-1,j,0),a);
        }
    }
    for(int i=1;i<n;i++){
        for(int j=1;j<=m;j++){
            int a; scanf("%d",&a);
            insert(get(i,j-1,1),get(i,j,0),a);
        }
    }
    for(int i=1;i<n;i++){
        for(int j=1;j<m;j++){
            int a; scanf("%d",&a);
            insert(get(i,j,0),get(i,j,1),a);
        }
    }
}
 
int main(){
    scanf("%d%d",&n,&m);
    init();
    printf("%d\n",Dijkstra(0,((n-1)*(m-1)<<1)+1));
    return 0;
}
View Code

 

 

 

 

BZOJ_1001_狼抓兔子(平面图求最小割+对偶图求最短路)

标签:

原文地址:http://www.cnblogs.com/Sunnie69/p/5491265.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!