zoukankan      html  css  js  c++  java
  • bzoj 4152[AMPPZ2014]The Captain

    bzoj 4152[AMPPZ2014]The Captain

    给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。
    一开始我居然把这个取min看成取曼哈顿距离。。
    暴力建图是(n^2)
    考虑两个点,可以以(|x_1-x_2|)(|y_1-y_2|)为权值分别建图,在跑最短路的时候也不会去走那条权值大的边,这样就不用再管(min)
    以以(|x_1-x_2|)为权值加边为例,有三个点(i),(j),(k),(x_ileq x_jleq x_k),则(dis(i,k)=dis(i,j)+dis(j,k)),所以只要把n个点按x排序,只把相邻两个点建一条边就行了
    (|y_1-y_2|)为权值时同理
    最后跑一遍最短路
    code.

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<iomanip>
    #include<cstring>
    #define R register
    #define EN std::puts("")
    #define LL long long
    inline int read(){
    	int x=0,y=1;
    	char c=std::getchar();
    	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
    	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
    	return y?x:-x;
    }
    struct point{
    	int x,y,id;
    }a[200006];
    int n;
    int fir[200006],nex[800006],to[800006],w[800008],tot;
    LL dis[200006];int in[200006];
    int dui[200006],size;
    inline void push(int x){
    	dui[size++]=x;
    	R int i=size-1,fa;
    	while(i){
    		fa=i>>1;
    		if(dis[dui[fa]]<=dis[dui[i]]) return;
    		std::swap(dui[fa],dui[i]);i=fa;
    	}
    }
    inline int pop(){
    	int ret=dui[0];dui[0]=dui[--size];
    	R int i=0,ls,rs;
    	while((i<<1)<size){
    		ls=i<<1;rs=ls|1;
    		if(rs<size&&dis[dui[rs]]<dis[dui[ls]]) ls=rs;
    		if(dis[dui[ls]]>=dis[dui[i]]) break;
    		std::swap(dui[ls],dui[i]);i=ls;
    	}
    	return ret;
    }
    inline int cmpx(point aa,point bb){return aa.x<bb.x;}
    inline int cmpy(point aa,point bb){return aa.y<bb.y;}
    inline void add(int x,int y,int z){
    	to[++tot]=y;w[tot]=z;
    	nex[tot]=fir[x];fir[x]=tot;
    }
    inline void dij(){
    	std::memset(dis,0x3f,sizeof dis);
    	dis[1]=0;push(1);in[1]=1;
    	while(size){
    		R int u=pop();in[u]=0;
    		for(R int i=fir[u];i;i=nex[i]){
    			R int v=to[i];
    			if(dis[v]>dis[u]+w[i]){
    				dis[v]=dis[u]+w[i];
    				if(!in[v]) push(v),in[v]=1;
    			}
    		}
    	}
    }
    int main(){
    	n=read();
    	for(R int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),a[i].id=i;
    	std::sort(a+1,a+1+n,cmpx);
    	for(R int i=1;i<n;i++)
    		add(a[i].id,a[i+1].id,a[i+1].x-a[i].x),
    		add(a[i+1].id,a[i].id,a[i+1].x-a[i].x);
    	std::sort(a+1,a+1+n,cmpy);
    	for(R int i=1;i<n;i++)
    		add(a[i].id,a[i+1].id,a[i+1].y-a[i].y),
    		add(a[i+1].id,a[i].id,a[i+1].y-a[i].y);
    	dij();
    	std::printf("%lld",dis[n]);
    	return 0;
    }
    
  • 相关阅读:
    记第一场省选
    POJ 2083 Fractal 分形
    CodeForces 605A Sorting Railway Cars 思维
    FZU 1896 神奇的魔法数 dp
    FZU 1893 内存管理 模拟
    FZU 1894 志愿者选拔 单调队列
    FZU 1920 Left Mouse Button 简单搜索
    FZU 2086 餐厅点餐
    poj 2299 Ultra-QuickSort 逆序对模版题
    COMP9313 week4a MapReduce
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/12527517.html
Copyright © 2011-2022 走看看