zoukankan      html  css  js  c++  java
  • hihocoder #1138 : Islands Travel

    题意,求1到n的最短路。不难想到单源最短路,难点在于数量级太大,因此如何建图是关键;
    
    因为cost =  min{|Xi-Xj|, |Yi-Yj|};所以,点i的移动只有两种情况,1. x距离最近的点,2. y距离最近的点 
    
    如此一来,每个点i的最多只有四条边(为什么是四条?),这样复杂度就降下来了,单源最短路的复杂度为n*m(点*边数) 
    
    我用spfa。 
    
    解题思路: 
    
    x轴排序,建图 
    
    y轴排序,建图 
    
    求最短路 
    
    用spfa注意队列que的大小至少是n*m,可以使用循环队列 
    
     
    
    
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <string>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int N = 100010;
    
    struct node
    {
        int v;
        int i;
        bool operator < (const node &t)const
        {
            return v < t.v;
        }
    }x[N],y[N];
    
    vector<int>g[N];
    int p[N][2];
    
    int ABS(int x)
    {
        return x >= 0 ? x : -x;
    }
    
    long long get_value(int i,int j)
    {
        return min(ABS(p[i][0]-p[j][0]),ABS(p[i][1]-p[j][1]));
    }
    
    bool flag[N];
    long long dist[N];
    int que[N];
    
    long long spfa(int s,int n)
    {
    
        memset(flag,false,sizeof(flag));
        memset(dist,0x7f,sizeof(dist));
        int head = 0,tail = 0;
        dist[s] = 0;
        flag[s] = true;
        que[tail++] = s;
        while(head != tail)
        {
            int tep = que[head++];
            if(head >= N) head = 0;//循环队列
    
            flag[tep] = false;
            for(int i = 0; i < g[tep].size(); i++)
            {
                int v = g[tep][i];
                if(dist[v] > dist[tep] + get_value(v,tep))
                {
                    dist[v] = dist[tep] + get_value(v,tep);
                    if(!flag[v])
                    {
                        que[tail++] = v;
                        if(tail >= N) tail = 0;//循环队列
    
                        flag[v] = true;
                    }
                }
            }
        }
        return dist[n-1];
    
    }
    
    
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            for(int i = 0; i < N; i++) g[i].clear();
            for(int i = 0; i < n; i++)
            {
    
                scanf("%d %d",&p[i][0],&p[i][1]);
                x[i].v = p[i][0]; x[i].i = i;
                y[i].v = p[i][1]; y[i].i = i;
            }
            sort(x,x+n);
            sort(y,y+n);
            for(int i = 1; i < n; i++)
            {
                int u = x[i-1].i;
                int v = x[i].i;
                //这里可以去下重
                g[u].push_back(v);
                g[v].push_back(u);
            }
            for(int i = 1; i < n; i++)
            {
                int u = y[i-1].i;
                int v = y[i].i;
                //这里可以去下重
                g[u].push_back(v);
                g[v].push_back(u);
            }
            printf("%lld
    ",spfa(0,n));
        }
        return 0;
    }
  • 相关阅读:
    IOC
    paxos算法
    搜索引擎相关
    java常识
    Redis相关概念
    Keepalived简单理解
    LVS简单理解
    dbproxy
    用不上索引的sql
    二叉树、B树、B+树、B*树、VAL树、红黑树
  • 原文地址:https://www.cnblogs.com/zendu/p/4980982.html
Copyright © 2011-2022 走看看