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\n",spfa(0,n));
    }
    return 0;
}
时间: 2024-10-07 02:49:35

hihocoder #1138 : Islands Travel的相关文章

hihocoder 1138 Islands Travel dijkstra+heap 难度:3

很久不用dijkstra,几乎连基本性质也忘了,结果这道题就是考察dijkstra空间复杂度是o(n) 这里总结四种算法 算法名称           时间复杂度       空间复杂度 dijkstra+heap  O(elog(e+n))   O(n) bellman-ford    O(ne)             O(n) spfa                O(ke)             O(n) floyd-warshall   O(n^3)          O(n^2)

HDU - 3405 - World Islands

先上题目: World Islands Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 888    Accepted Submission(s): 345 Problem Description Dubai is a haven for the rich. The government of Dubai finds a good way

hihocoder 1038

http://hihocoder.com/problemset/problem/1138 题意:有一些岛屿,要从第一个岛屿到第N个岛屿,求最短距离,距离为min(x,y),也就是两个点的X的差值和Y的差值的较小的. 思路:最开始我觉得应该dijstrak可以解决,因为是LEVEL1的,结果超时了,我就想是不是head+dijstrak..结果是的,不过这个题可以用SPFA做 优化的部分也就是说对于每一个点,拓展4个边就可以,就是x差值最小的两个点,和y差值最小的两个点. 1 #include <

hihoCoder 1578 Visiting Peking University 【贪心】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

#1578 : Visiting Peking University 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Ming is going to travel for n days and the date of these days can be represented by n integers: 0, 1, 2, -, n-1. He plans to spend m consecutive days(2 ≤ m ≤ n)in Beijing. Durin

环绕岛屿Surround the Islands

题目描述 Farmer John has bought property in the Caribbean and is going to try to raise dairy cows on a big farm composed of islands. Set in his ways, he wants to surround all the islands with fence. Each island in the farm has the shape of a polygon. He

[hihoCoder#1381]Little Y&#39;s Tree

[hihoCoder#1381]Little Y's Tree 试题描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每次小J会删掉这个树中的k条边,这棵树被分成k+1个连通块.小J想知道每个连通块中最远点对距离的和. 这里的询问是互相独立的,即每次都是在小Y的原树上进行操作. 输入 第一行一个整数n,接下来n-1行每行三个整数u,v,w,其中第i行表示第i条边边权为wi,连接了ui,vi两点. 接下来一行一个整数q,表示有q组询问. 对于每组询问,第一行一个正整数k,接下来一

hihoCoder 1175:拓扑排序二

题目链接: http://hihocoder.com/problemset/problem/1175 题目难度:一星级(简单题) 今天闲来无事,决定刷一道水题.结果发现这道水题居然把我卡了将近一个钟头. 最后终于调通了.总结起来,原因只有一个:不够仔细. 思路不用细说了,就是拓扑排序的简单应用.然而,一些不起眼的细节才是让你掉坑里的真正原因. 猜猜哪儿可能出bug? // A simple problem, but you can't be too careful with it. #inclu

51nod 1138 连续整数的和(数学)

题目描述: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1138 给出一个正整数N,将N写为若干个连续数字和的形式(长度 >= 2).例如N = 15,可以写为1 + 2 + 3 + 4 + 5,也可以写为4 + 5 + 6,或7 + 8.如果不能写为若干个连续整数的和,则输出No Solution. Input 输入1个数N(3 <= N <= 10^9). OutPut 输出连续整数中的第1个数,如果有多

UVA 1048 - Low Cost Air Travel(最短路)

UVA 1048 - Low Cost Air Travel 题目链接 题意:给定一些联票,在给定一些行程,要求这些行程的最小代价 思路:最短路,一张联票对应几个城市就拆成多少条边,结点表示的是当前完成形成i,在城市j的状态,这样去进行最短路,注意这题有坑点,就是城市编号可能很大,所以进行各种hash 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #in