• bzoj4152 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
     
     
    又一道卡spfa的最短路题,学长HugeGun说用堆优dijkstra就好,但是我只会spfa,然后狂T,又以为有什么智障错误内心紧张无比。
    分别根据横坐标和纵坐标排两次序,把每次排好序后相邻的连边(似乎以前有学长讲过?)。
    最近连续遇到两道卡spfa的题了,或许真的应该学一学堆优dijkstra。
    用SLF优化的spfa刚好卡过的代码:
    //Serene
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int maxn=2e5+10,maxm=4e5+10;
    int n;
    
    int aa;char cc;
    int read() {
    	aa=0;cc=getchar();
    	while(cc<'0'||cc>'9') cc=getchar();
    	while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
    	return aa;
    }
    
    struct Node1{
    	int pos,x;
    }node1[maxn];
    
    struct Node2{
    	int pos,x;
    }node2[maxn];
    
    bool cmp1(const Node1& a,const Node1& b) {
    	return a.x<b.x;
    }
    
    bool cmp2(const Node2& a,const Node2& b) {
    	return a.x<b.x;
    }
    
    int fir[maxn],nxt[2*maxm],to[2*maxm],v[2*maxm],e=0;
    void add(int x,int y,int z) {
    	to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z;
    	to[++e]=x;nxt[e]=fir[y];fir[y]=e;v[e]=z;
    }
    
    int dis[maxn],zz[maxn];
    bool vis[maxn];
    void spfa() {
    	for(int i=2;i<=n;++i) dis[i]=0x3f3f3f3f;
    	int s=1,t=0,x,y,z,tot=1;
    	dis[1]=0;zz[++t]=1;vis[1]=1;
    	while(tot) {
    		x=zz[s];s=(s+1)%maxn;vis[x]=0;tot--;
    		for(y=fir[x];y;y=nxt[y]) {
    			z=to[y];
    			if(dis[z]<=dis[x]+v[y]) continue;
    			dis[z]=dis[x]+v[y];
    			if(!vis[z]) {
    				vis[z]=1;tot++;
    				if(dis[z]<=dis[zz[s]]) {
    					s=(s-1+maxn)%maxn;
    					zz[s]=z;
    				}
    				else {
    					t=(t+1)%maxn;
    					zz[t]=z;
    				}
    			}
    		}
    	}
    	printf("%d",dis[n]);
    }
    
    int main() {
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i) {
    		node1[i].pos=node2[i].pos=i;
    		scanf("%d%d",&node1[i].x,&node2[i].x);
    	}
    	sort(node1+1,node1+n+1,cmp1);
    	for(int i=1;i<n;++i) add(node1[i].pos,node1[i+1].pos,node1[i+1].x-node1[i].x);
    	sort(node2+1,node2+n+1,cmp2);
    	for(int i=1;i<n;++i) add(node2[i].pos,node2[i+1].pos,node2[i+1].x-node2[i].x);
    	spfa();
    	return 0;
    }
    

      

    弱者就是会被欺负呀
  • 相关阅读:
    Android 调用已安装市场,进行软件评分的功能实现
    二十六个月Android学习工作总结
    Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1) 错误 解决方案(android-ndk)
    【Android】神奇的android:clipChildren属性
    Android利用setLayoutParams在代码中调整布局(Margin和居中)
    android 使用代码实现 RelativeLayout布局
    Android 布局学习
    Erlang cowboy 处理不规范的client
    HTTP 响应
    把字符串转换为整数
  • 原文地址:https://www.cnblogs.com/Serene-shixinyi/p/7534964.html
Copyright © 2020-2023  润新知