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;
    }
    
  • 相关阅读:
    SQLServer数据库优化常用语句
    雷军:用互联网思维改造传统产业
    互联网公司该向东莞学什么?
    企业管理:中层领导必看:什么叫工作到位?
    Web页面工作流设计器
    雷军:用互联网思维改造传统产业
    生成html页面客户端随机数和验证码
    IIS应用程序池频繁停止,任务管理器发现有多个w3wp.exe进程
    检测SqlServer服务器性能
    利用任务计划自动删除指定日期文件
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9556246.html
Copyright © 2011-2022 走看看