zoukankan      html  css  js  c++  java
  • BZOJ4152: [AMPPZ2014]The Captain

    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],y[i](0<=x[i],y[i]<=10^9),依次表示每个点的坐标。

    Output

    一个整数,即最小费用。

    Sample Input

    5
    2 2
    1 1
    4 5
    7 1
    6 7

    Sample Output

    2

    题解Here!
    这题显然直接$SPFA$对吧。。。
    但是那个建图怎么搞?
    $O(n^2) ext{的Force?} an(frac{pi}{2}+kpi),kin Z$。。。
    我们不难发现这样一个事实:
    如果有一个点$P$在$M,N$两个点之间,从$M$到$N$得代价一定大于从$M$到$P$,再从$P$到$N$得代价。
    换言之,我们的边应该建在横纵坐标相邻的点之间。 
    这就是一个贪心啊。。。
    为此目的,我们把点们按照横坐标从小到大排序,再把点们按照纵坐标从小到大排序。
    然后直接按排好的顺序在相邻两个节点之间建双向边。
    然后直接$SPFA$即可。
    然而,出题人很不友好。。。
    这题卡$SPFA$!这题卡$SPFA+SLF$!!这题卡$SPFA+SLF+LLL$!!!重要的事情说三遍!!!
    害得我只能写堆优化$Dijkstra$。。。
    附代码:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #define MAXN 200010
    #define MAX (1LL<<61)
    using namespace std;
    int n,s,t,c=1;
    int head[MAXN];
    long long path[MAXN];
    bool vis[MAXN];
    struct Point{
    	int x,y,id;
    }point[MAXN];
    struct Edge{
    	int next,to;
    	long long w;
    }a[MAXN<<2];
    struct node{
        int x,dis;
        bool operator <(const node &p)const{
            return dis>p.dis;
        }
    };
    priority_queue<node> q;
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    inline bool cmp1(const Point &p,const Point &q){
    	return p.x<q.x;
    }
    inline bool cmp2(const Point &p,const Point &q){
    	return p.y<q.y;
    }
    inline int relax(int u,int v,long long w){
    	if(path[v]>path[u]+w){
    		path[v]=path[u]+w;
    		return 1;
    	}
    	return 0;
    }
    inline void add(int u,int v,int w){
    	a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;
    	a[c].to=u;a[c].w=w;a[c].next=head[v];head[v]=c++;
    }
    void dijkstra(){
        node u,v;
        for(int i=1;i<=n;i++){path[i]=MAX;vis[i]=false;}
        u.x=s;u.dis=path[s]=0;
        q.push(u);
        while(!q.empty()){
            u=q.top();
            q.pop();
            if(!vis[u.x]){
                vis[u.x]=true;
                for(int i=head[u.x];i;i=a[i].next){
                    v.x=a[i].to;
                    if(!vis[v.x]){
                        path[v.x]=min(path[v.x],path[u.x]+a[i].w);
                        v.dis=u.dis+a[i].w;
                        q.push(v);
                    }
                }
            }
        }
    }
    void work(){
    	dijkstra();
    	printf("%lld
    ",path[t]);
    }
    void init(){
    	n=read();
    	s=1;t=n;
    	for(int i=1;i<=n;i++){
    		point[i].x=read();point[i].y=read();
    		point[i].id=i;
    	}
    	sort(point+1,point+n+1,cmp1);
    	for(int i=1;i<n;i++)add(point[i].id,point[i+1].id,point[i+1].x-point[i].x);
    	sort(point+1,point+n+1,cmp2);
    	for(int i=1;i<n;i++)add(point[i].id,point[i+1].id,point[i+1].y-point[i].y);
    }
    int main(){
    	init();
    	work();
        return 0;
    }
    
  • 相关阅读:
    C# 不用添加WebService引用,调用WebService方法
    贪心 & 动态规划
    trie树 讲解 (转载)
    poj 2151 Check the difficulty of problems (检查问题的难度)
    poj 2513 Colored Sticks 彩色棒
    poj1442 Black Box 栈和优先队列
    啦啦啦
    poj 1265 Area(pick定理)
    poj 2418 Hardwood Species (trie树)
    poj 1836 Alignment 排队
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9556246.html
Copyright © 2011-2022 走看看