hiho #1138 : Islands Travel 【最短路】

来源:互联网 发布:单机游戏数据修改器 编辑:程序博客网 时间:2024/06/08 18:42

#1138 : Islands Travel

Time Limit:10000ms
Case Time Limit:1000ms
Memory Limit:256MB

Description

There are N islands on a planet whose coordinates are (X1, Y1), (X2, Y2), (X3, Y3) ..., (XN, YN). You starts at the 1st island (X1, Y1) and your destination is the n-th island (XN, YN). Travelling between i-th and j-th islands will cost you min{|Xi-Xj|, |Yi-Yj|} (|a| denotes the absolute value of a. min{a, b} denotes the smaller value between a and b) gold coins. You want to know what is the minimum cost to travel from the 1st island to the n-th island.

Input

Line 1: an integer N.

Line 2~N+1: each line contains two integers Xi and Yi.


For 40% data, N<=1000,0<=Xi,Yi<=100000.

For 100% data, N<=100000,0<=Xi,Yi<=1000000000.

Output

Output the minimum cost.

Sample Input
32 21 77 6
Sample Output
2
题意:给你n个岛屿的坐标,i到j的花费为min(abs(x[i]-x[j]), abs(y[i]-y[j]))。问你1-n的最小花费。


思路:n比较大,不能直接搞。需要把图简化,先按x坐标是否相等划分集合,集合内部的点边权为0,两个邻近的集合建边,同理搞下y。其它集合不需要建边,因为到达第i个集合的最优路径一定会经过其邻近集合。画下图就很清楚了。


AC代码:


#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <set>#include <vector>#include <string>#define INF 1000000#define eps 1e-8#define MAXN (100000+10)#define MAXM (2000000+10)#define Ri(a) scanf("%d", &a)#define Rl(a) scanf("%lld", &a)#define Rf(a) scanf("%lf", &a)#define Rs(a) scanf("%s", a)#define Pi(a) printf("%d\n", (a))#define Pf(a) printf("%.2lf\n", (a))#define Pl(a) printf("%lld\n", (a))#define Ps(a) printf("%s\n", (a))#define W(a) while((a)--)#define CLR(a, b) memset(a, (b), sizeof(a))#define MOD 1000000007#define LL long long#define lson o<<1, l, mid#define rson o<<1|1, mid+1, r#define ll o<<1#define rr o<<1|1#define PI acos(-1.0)#pragma comment(linker, "/STACK:102400000,102400000")#define fi first#define se secondusing namespace std;typedef pair<int, int> pii;struct Edge{    int to, val, next;};Edge edge[MAXM];int head[MAXN], edgenum;int dist[MAXN]; bool vis[MAXN];void init(){CLR(head, -1); edgenum = 0;}void addEdge(int u, int v, int w){    Edge E = {v, w, head[u]};    edge[edgenum] = E;    head[u] = edgenum++;}int n;int Spfa(){    CLR(dist, INF); CLR(vis, false);    queue<int> Q; Q.push(1); vis[1] = true; dist[1] = 0;    while(!Q.empty())    {        int u = Q.front(); Q.pop(); vis[u] = false;        for(int i = head[u]; i != -1; i = edge[i].next)        {            int v = edge[i].to;            if(dist[v] > dist[u] + edge[i].val)            {                dist[v] = dist[u] + edge[i].val;                if(!vis[v])                {                    vis[v] = true;                    Q.push(v);                }            }        }    }    return dist[n];}struct Node{    int x, y, id;};Node In[MAXN];bool cmp1(Node a, Node b){    if(a.x != b.x) return a.x < b.x;    return a.y < b.y;}bool cmp2(Node a, Node b){    if(a.y != b.y) return a.y < b.y;    return a.x < b.x;}int main(){    while(Ri(n) != EOF)    {        for(int i = 0; i < n; i++) Ri(In[i].x), Ri(In[i].y), In[i].id = i+1;        init();        sort(In, In+n, cmp1); int i = 0, j;        while(i < n)        {            j = i+1;            while(j < n && In[i].x == In[j].x)            {                addEdge(In[i].id, In[j].id, 0);                addEdge(In[j].id, In[i].id, 0);                j++;            }            if(j < n)            {                addEdge(In[i].id, In[j].id, In[j].x - In[i].x);                addEdge(In[j].id, In[i].id, In[j].x - In[i].x);            }            i = j;        }        i = 0; sort(In, In+n, cmp2);        while(i < n)        {            j = i+1;            while(j < n && In[i].y == In[j].y)            {                addEdge(In[i].id, In[j].id, 0);                addEdge(In[j].id, In[i].id, 0);                j++;            }            if(j < n)            {                addEdge(In[i].id, In[j].id, In[j].y - In[i].y);                addEdge(In[j].id, In[i].id, In[j].y - In[i].y);            }            i = j;        }        Pi(Spfa());    }    return 0;}


2 0
原创粉丝点击