• bzoj4152-[AMPPZ2014]The_Captain


    Description

    给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。

    Input

    第一行包含一个正整数n(2<=n<=200000),表示点数。
    接下来n行,每行包含两个整数x[i],yi,依次表示每个点的坐标。

    Output

    一个整数,即最小费用。

    Sample Input

    5

    2 2

    1 1

    4 5

    7 1

    6 7

    Sample Output

    2

    Solution

    定义 (d_{i,j} = min(x_i - x_j, y_i - y_j)).

    (x_i <= x_j <= x_k), 发现 (d_{i,k} >= d_{i,j} + d_{j,k}). (y) 同理.

    因此, 将x轴排序, 将x坐标相邻的点相连, y轴同理. 求1到n最短路即可.

    Code

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    #define rep(i,l,r) for(register int i=(l);i<=(r);++i)
    #define repdo(i,l,r) for(register int i=(l);i>=(r);--i)
    #define il inline
    typedef double db;
    typedef long long ll;
    
    //---------------------------------------
    const int nsz=2e5+50;
    const ll ninf=1e17;
    
    int n;
    struct tp{int p,x,y;}line[nsz];
    bool cmp1(tp a,tp b){return a.x<b.x;}
    bool cmp2(tp a,tp b){return a.y<b.y;}
    int dis(int a,int b){return min(abs(line[a].x-line[b].x),abs(line[a].y-line[b].y));}
    
    struct te{int t,v,pr;}edge[nsz*4];
    int hd[nsz],pe=1;
    void adde(int f,int t,int v){edge[++pe]=(te){t,v,hd[f]};hd[f]=pe;}
    void adddb(int f,int t,int v){adde(f,t,v);adde(t,f,v);}
    
    ll mind[nsz],vi[nsz];
    struct tnd{ll v,d;};
    bool operator<(tnd a,tnd b){return a.d>b.d;}
    void dij(int f){
    	priority_queue<tnd> pq;
    	rep(i,1,n)mind[i]=ninf,vi[i]=0;
    	mind[f]=0,pq.push((tnd){f,0});
    	int u,d2;
    	while(!pq.empty()){
    		u=pq.top().v;pq.pop();
    		if(vi[u])continue;
    		vi[u]=1;
    		for(int i=hd[u],v;i;i=edge[i].pr){
    			v=edge[i].t,d2=mind[u]+edge[i].v;
    			if(mind[v]>d2){
    				mind[v]=d2;
    				pq.push((tnd){v,mind[v]});
    			}
    		}
    	}
    }
    int main(){
    	ios::sync_with_stdio(0),cin.tie(0);
    	cin>>n;
    	rep(i,1,n)cin>>line[i].x>>line[i].y,line[i].p=i;
    	sort(line+1,line+n+1,cmp1);
    	rep(i,1,n-1)adddb(line[i].p,line[i+1].p,dis(i,i+1));
    	sort(line+1,line+n+1,cmp2);
    	rep(i,1,n-1)adddb(line[i].p,line[i+1].p,dis(i,i+1));
    	dij(1);
    	cout<<mind[n]<<'
    ';
    	return 0;
    }
    
    
  • 相关阅读:
    linux
    linux
    linux
    linux
    linux
    linux
    linux
    idea插件篇之java内存分析工具(JProfiler)
    Jmeter(线程组+http请求+汇总报告)
    ZK客户端zkClient.bat
  • 原文地址:https://www.cnblogs.com/ubospica/p/10237579.html
Copyright © 2020-2023  润新知