hiho #1138 : Islands Travel 【最短路】
2016-02-10 18:57
369 查看
#1138 : Islands Travel
Time Limit:10000msCase 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
3 2 2 1 7 7 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 second using 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 ; } 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; }
相关文章推荐
- hdoj 5623 KK's Number 【dp】
- hdoj 5621 KK's Point 【数学】
- hdoj 5620 KK's Steel 【数学】
- 统计字符串中单词的个数
- 在Linux机上配置Eclipse并部署Maven
- 自己做题的简单的算法
- Jquery封装之----事件绑定(一)
- spring(AOP)静态代理、JDK动态代理、cglib实现代理
- 函数指针&绑定: boost::functoin/std::function/bind
- SendMessage和PostMessage
- 更新时提示“windows update 更新错误代码8000FFF 无法更新”。
- Debian常用软件
- 斐波那契数列
- JavaScript高级程序设计学习笔记第十章--DOM
- Eclipse使用
- scrapy爬虫代理——利用crawlera神器,无需再寻找代理IP
- hdu5233 邻接表 两组代码,一组AC,一组不知道为什么RE了(以后再看)
- Xcode 【Asset Catalog】
- 使用Dom4j时遇到的两个问题
- 初涉网络,自己对服务器的一些基础理解