• D. Returning Home 最短路


    D. Returning Home 最短路

    题目大意:

    你现在位于位置 ((sx,sy)) ,你家的位置是 ((gx,gy)) ,你在一个大小 (n*n) 的网格中行走,在一分钟之内,你可以往相邻的格子走动一格,这里有 (m) 个特殊的点,如果你走到的点和特殊的点在同一x坐标轴或者y坐标轴,那么可以马上出现在这些特殊的点,问你回到家的最短的时间。

    题解:

    这个题目很明显就是这m个点相互建边,然后跑最短路。

    但是m有1e5,所以复杂度会到1e10,所以不能直接建边,要建一些辅助点。

    这个辅助点,就是x和y,对于每一个不同的x都建一个点,对于每一个不同的y都建一个点,

    然后建边,跑dij就可以了。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 1e6+10;
    const int mod = 1e9+7;
    int head[maxn],nxt[maxn<<1],to[maxn<<1],w[maxn<<1],cnt;
    void add(int u,int v,ll c){
    	// printf("u = %d v = %d c = %lld
    ", u,v,c);
    	++cnt,to[cnt]=v,w[cnt]=c,nxt[cnt]=head[u],head[u]=cnt;
    	++cnt,to[cnt]=u,w[cnt]=c,nxt[cnt]=head[v],head[v]=cnt;
    }
    
    struct heapnode{
    	ll d,u;
    	heapnode(ll d=0,ll u=0) : d(d),u(u) {}
    	bool operator<(const heapnode &a) const{
    	    return a.d<d;
    	}
    };
    ll d[maxn];
    bool vis[maxn];
    priority_queue<heapnode>que;
    void dijkstra(int s,int n){
    	while(!que.empty()) que.pop();
    	for(int i=0;i<=n;i++) d[i]=inf64,vis[i] = false;
    	d[s]=0,que.push(heapnode(0,s));
    	while(!que.empty()){
    		heapnode x=que.top();que.pop();
    		int u=x.u;
    		if(vis[u]) continue;
    		vis[u]=true;
    		for(int i=head[u];i;i=nxt[i]){
    			int v = to[i];
    			if(d[v]>d[u]+w[i]){
    				d[v]=d[u]+w[i];
    				que.push(heapnode(d[v],v));
    			}
    		}
    	}
    }
    
    int a[maxn],b[maxn],x[maxn],y[maxn];
    int main(){
    	int n,m,sx,sy,gx,gy;
    	scanf("%d%d",&n,&m);
    	scanf("%d%d%d%d",&sx,&sy,&gx,&gy);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d",&x[i],&y[i]);
    		a[i] = x[i],b[i] = y[i];
    	}
    	sort(a+1,a+1+m);
    	sort(b+1,b+1+m);
    	add(0,3*m+1,abs(sx-gx)+abs(sy-gy));
    	for(int i=2;i<=m;i++){
    		add(i+m,i+m-1,abs(a[i]-a[i-1]));
    		add(i+2*m,i+2*m-1,abs(b[i]-b[i-1]));
    	}
    	for(int i=1;i<=m;i++){
    		add(0,i,min(abs(sx-x[i]),abs(sy-y[i])));
    		add(i,3*m+1,abs(gx-x[i])+abs(gy-y[i]));
    		int pos1 = lower_bound(a+1,a+1+m,x[i])-a;
    		add(i,pos1+m,0);
    		int pos2 = lower_bound(b+1,b+1+m,y[i])-b;
    		add(i,pos2+2*m,0);
    	}
    	dijkstra(0,3*m+1);
    	printf("%lld
    ", d[3*m+1]);
    	return 0;
    }
    
  • 相关阅读:
    《数据结构》C++代码 线性表
    《数据结构》C++代码 Splay
    《数据结构》C++代码 前言
    蓝桥杯- 算法提高 最大乘积
    HDU-1241 Oil Deposits
    一个简单的网站计数器
    编写一个jsp页面,输出九九乘法表。
    Sum It Up
    历届试题 剪格子
    历届试题 分糖果
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13771893.html
Copyright © 2020-2023  润新知