• 【bzoj4152】【The Captain】最短路(堆优化)(浅尝ACM-B)


    这里写图片描述
    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=62834538

    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

    自然是想到最短路,但一看数据范围,妈呀,吓傻了。dijkstra?o(n*n)的复杂度(当时还不知道有堆优化这东西),肯定TLE。用spfa,竟然也TLE了!?

    首先是如何建边的问题,如果把所有的点都建边就太大了,空间都爆了。仔细看题,再画图一思考,即发现只需把x轴、y轴上相邻的的点连起来(明显比其他点优)。由此一来,每个点做多就连4条边。

    然后就是算法的优化了。这道题卡spfa,明显摆明了要你用优化。dijktra或spfa都可以用堆优化,手打太麻烦,可以用STL里的优先队列(才学到,长知识了)。dijktra打丑了,一直wa,无可奈何只有改打spfa,结果一遍ac,spfa大法好!

    坑点还是蛮多的,放在代码里面了

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define ll long long 
    using namespace std;
    
    const int N=200000+5;
    
    int n;
    int head[N],end[4*N],nxt[4*N],dis[4*N],hh=0;
    struct Node{
        int num,x,y;
    }a[N];
    ll dist[N];bool vis[N],con[N];
    
    void adde(int a,int b,int di){
        hh++;
        end[hh]=b;
        dis[hh]=di;
        nxt[hh]=head[a];
        head[a]=hh;
    }
    /*struct cmp{
        bool operator()(int a,int b){
            return dist[a]>dist[b];
        }
    };*/
    bool cmp1(Node a,Node b){
        return a.x<b.x;
    }
    bool cmp2(Node a,Node b){
        return a.y<b.y;
    }
    int abs(int a){
        return a<0?-a:a;
    }
    /*写wa了的dijkstra
    ll dijkstra(int st,int en){
        priority_queue<int,vector<int>,cmp> q;
        memset(dist,0x3f,sizeof(dist));
        dist[st]=0;
        vis[st]=1;
        con[st]=1;
        q.push(st);
        while(!q.empty()){
            int u=q.top();q.pop();
            con[u]=1;
            if(u==en) break;
            for(int i=head[u];i;i=nxt[i]){
                int v=end[i],di=dis[i];//printf("%d ",v);
                if(con[v]==1) continue;
                if(dist[u]+(ll)di<dist[v]){
                    dist[v]=dist[u]+(ll)di;
                    if(!vis[v]){
                        q.push(v);
                        vis[v]=1;
                    }
                }
            }
        }
        return dist[en];
    }*/
    ll spfa(int st,int en){
        memset(dist,0x3f,sizeof(dist));
        memset(vis,0,sizeof(vis));
        priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > q;//优先队列(堆)
        q.push(make_pair(0,st));
        vis[st]=1;
        dist[st]=0;
        while(!q.empty()){
            int u=q.top().second;
            q.pop();//q是优先队列,后pop可能就不是u了 
            vis[u]=0;//还可能会被更新
            for(int i=head[u];i;i=nxt[i]){
                int v=end[i],di=dis[i];
                if(dist[v]>dist[u]+di){
                    dist[v]=dist[u]+di;
                    if(!vis[v]){
                        q.push(make_pair(dist[v],v));
                        vis[v]=1;
                    }
                }
            }
        }
        return dist[en];
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
            a[i].num=i;
        }
        sort(a+1,a+n+1,cmp1);
        for(int i=1;i<=n;i++){
            if(i>1) adde(a[i].num,a[i-1].num,min(a[i].x-a[i-1].x,abs(a[i].y-a[i-1].y)));//建边要注意了,x轴上相邻的点可能y轴上的距离更近
            if(i<n) adde(a[i].num,a[i+1].num,min(a[i+1].x-a[i].x,abs(a[i].y-a[i+1].y)));
        }
        sort(a+1,a+n+1,cmp2);
        for(int i=1;i<=n;i++){
            if(i>1) adde(a[i].num,a[i-1].num,min(a[i].y-a[i-1].y,abs(a[i].x-a[i-1].x)));
            if(i<n) adde(a[i].num,a[i+1].num,min(a[i+1].y-a[i].y,abs(a[i].x-a[i+1].x)));
        }
        printf("%lld",/*dijkstra(1,n)*/spfa(1,n));
        return 0;
    }
  • 相关阅读:
    oc对象的内存管理
    OC类的本质,深入探讨,load方法和initialize方法
    OC特有语法:分类category,给NSString增加方法计算字符串中数字的个数
    OC的类的构造方法
    OC的@property 和 @synthesize id
    HTML5 Canvas时间效果
    各浏览器的Hack写法【转】
    你自认为理解了JavaScript?【转】
    八大疯狂的HTML5 Canvas及WebGL动画效果——8 CRAZY ANIMATIONS WITH WEBGL AND HTML5 CANVAS【收藏】
    一些达成共识的JavaScript编码风格约定【转】
  • 原文地址:https://www.cnblogs.com/LinnBlanc/p/7763162.html
Copyright © 2020-2023  润新知