zoukankan      html  css  js  c++  java
  • BZOJ 1001: [BeiJing2006]狼抓兔子(最短路)

    传送门

    解题思路

      平面图转对偶图,然后跑最短路。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    
    using namespace std;
    const int N=1405;
    
    inline int rd(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
    	while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return f?x:-x;
    }
    
    int n,m,head[N*N],cnt,to[N*N*6],nxt[N*N*6],val[N*N*6];
    int S,T,dis[N*N],Min=1e9;
    bool vis[N*N];
    
    struct Node{
    	int id,w;
    	friend bool operator<(const Node A,const Node B){
    		return A.w>B.w;
    	}
    	Node(int _id=0,int _w=0){id=_id;w=_w;}
    };
    priority_queue<Node> Q;
    
    inline void add(int bg,int ed,int w){
    	to[++cnt]=ed,nxt[cnt]=head[bg],val[cnt]=w,head[bg]=cnt;
    	to[++cnt]=bg,nxt[cnt]=head[ed],val[cnt]=w,head[ed]=cnt;
    }
    
    void dijkstra(){
    	memset(dis,0x3f,sizeof(dis));
    	dis[S]=0; Q.push(Node(S,0));
    	while(Q.size()){
    		Node now=Q.top(); Q.pop();
    		if(dis[now.id]!=now.w || vis[now.id]) continue;
    		int x=now.id;vis[x]=1;
    		for(int i=head[x];i;i=nxt[i]){
    			int u=to[i];
    			if(dis[x]+val[i]<dis[u]){
    				dis[u]=dis[x]+val[i];
    				Q.push(Node(u,dis[u]));
    			}
    		}
    	}
    }
    
    int main(){
    	n=rd(),m=rd(); int w; S=0;T=2*(n-1)*(m-1)+1;
    	if(n==1 && m==1) {puts("0");return 0;}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<m;j++){scanf("%d",&w); Min=min(Min,w);
    			if(i==1) add(2*j,T,w);
    			else if(i==n) add(S,(i-2)*2*(m-1)+2*j-1,w);
    			else add((i-2)*2*(m-1)+2*j-1,(i-1)*2*(m-1)+2*j,w);
    		}
    	for(int i=1;i<n;i++)
    		for(int j=1;j<=m;j++){scanf("%d",&w); Min=min(Min,w);
    			if(j==1) add(S,(i-1)*2*(m-1)+2*j-1,w);
    			else if(j==m) add((i-1)*2*(m-1)+2*(j-1),T,w);
    			else add((i-1)*2*(m-1)+2*(j-1),(i-1)*2*(m-1)+2*j-1,w);
    		}
    	if(n==1 || m==1) {printf("%d
    ",Min);return 0;}
    	for(int i=1;i<n;i++)
    		for(int j=1;j<m;j++){scanf("%d",&w);
    			add((i-1)*2*(m-1)+2*j-1,(i-1)*2*(m-1)+2*j,w);
    		}
    	dijkstra(); printf("%d
    ",dis[T]);
    	return 0;
    }
    
  • 相关阅读:
    plsql使用技巧(转)
    tomcat启动报错:Address already in use: JVM_Bind(转)
    多行文本超出时显示省略号----jquery.ellipsis.js(转)
    SVN使用教程总结(转)
    Navicat Premium 12.0.18安装与激活(转)
    Java编程思想 阅读笔记 第一章 对象导论
    Examples--Basic initialisation
    spring(最新) jar 包下载
    JUC并发编程笔记
    Java 整数的内存分析
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10299235.html
Copyright © 2011-2022 走看看