[BZOJ 4152] The Captain 最短路(Dijkstra版)
2017-07-05 21:46
465 查看
题目传送门:【BZOJ 4152】
题目大意:给定平面上的 n 个点,定义 ( x1 , y1 ) 到 ( x2 , y2 ) 的距离为 min ( | x1 - x2 | , | y1 - y2 | ),求从 1 号点走到 n 号点的最小距离。(原题为费用,不过在这里是等效的)
(2 ≤ n ≤ 2*105,0 ≤ ∣x∣ , ∣y∣ ≤ 109)
题目分析:
一道考察对题目理解的最短路的好题。
首先,根据题意,这道题肯定与最短路有关。不过我们该怎么去经过最短路的边呢?
容易看到这里题目对两点间的距离作出了定义:两点间距离为它们的 X 轴坐标值之差和 Y 轴坐标值之差的最小值。因此我们可以根据题意,令上述的最小值为两点之间的边长,然后对任意两点建边。
不过总共有 20 万个点,对任意两点建边显然是不可能的。注意到绝大部分的边都是不用建的。其实,我们只需要建立对最短路可能有贡献的边;根据题意,边长为 min ( | x1 - x2 | , | y1 - y2 | ),那么我们对每个点进行两次排序:
先对所有点的 X 坐标排序,然后对相邻的两个点连边(想一想,为什么);然后对所有点的 Y 坐标排序,再对相邻两点建边。(这里可以进行优化,但是为了理解和写起来方便,这样其实已经够了)
建好边之后,跑一遍最短路便可求出 1 号点到 n 号点的最小距离。
本题据说会卡 SPFA!
下面附上 Dijkstra 的代码:
题目大意:给定平面上的 n 个点,定义 ( x1 , y1 ) 到 ( x2 , y2 ) 的距离为 min ( | x1 - x2 | , | y1 - y2 | ),求从 1 号点走到 n 号点的最小距离。(原题为费用,不过在这里是等效的)
(2 ≤ n ≤ 2*105,0 ≤ ∣x∣ , ∣y∣ ≤ 109)
题目分析:
一道考察对题目理解的最短路的好题。
首先,根据题意,这道题肯定与最短路有关。不过我们该怎么去经过最短路的边呢?
容易看到这里题目对两点间的距离作出了定义:两点间距离为它们的 X 轴坐标值之差和 Y 轴坐标值之差的最小值。因此我们可以根据题意,令上述的最小值为两点之间的边长,然后对任意两点建边。
不过总共有 20 万个点,对任意两点建边显然是不可能的。注意到绝大部分的边都是不用建的。其实,我们只需要建立对最短路可能有贡献的边;根据题意,边长为 min ( | x1 - x2 | , | y1 - y2 | ),那么我们对每个点进行两次排序:
先对所有点的 X 坐标排序,然后对相邻的两个点连边(想一想,为什么);然后对所有点的 Y 坐标排序,再对相邻两点建边。(这里可以进行优化,但是为了理解和写起来方便,这样其实已经够了)
建好边之后,跑一遍最短路便可求出 1 号点到 n 号点的最小距离。
本题据说会卡 SPFA!
下面附上 Dijkstra 的代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; const int MX = 200005; const int INF = 0x3f3f3f3f; struct Edge{ //之后建立的边 int next,to,len; }; Edge edge[4 * MX]; struct Map{ //输入的坐标 int x,y,cnt; }; Map map[MX]; struct Heapnode{ int d,u; bool operator < (const Heapnode& r) const { return d > r.d; } }; int n,now = 0,head[MX],dis[MX]; bool vis[MX] = {0}; bool comp_x(Map i,Map j){return i.x < j.x;} bool comp_y(Map i,Map j){return i.y < j.y;} void adde(int u,int v,int l){ edge[++now].to = v; edge[now].len = l; edge[now].next = head[u]; head[u] = now; } void dijkstra(int s){ priority_queue<Heapnode> q; memset(dis,0x3f,sizeof(dis)); dis[s] = 0; q.push((Heapnode) {0,s}); while (!q.empty()){ int u = q.top().u; q.pop(); if (vis[u]) continue; vis[u] = true; for (int i = head[u];i;i = edge[i].next){ int v = edge[i].to; if (dis[u] + edge[i].len < dis[v]){ dis[v] = dis[u] + edge[i].len; q.push((Heapnode) {dis[v],v}); } } } } int main(){ cin>>n; for (int i = 1;i <= n;i++){ cin>>map[i].x>>map[i].y; map[i].cnt = i; } sort(map+1,map+n+1,comp_x); for (int i = 2;i <= n;i++){ if (map[i].x - map[i-1].x <= abs(map[i].y - map[i-1].y)){ adde(map[i-1].cnt , map[i].cnt , map[i].x-map[i-1].x); adde(map[i].cnt , map[i-1].cnt , map[i].x-map[i-1].x); } } sort(map+1,map+n+1,comp_y); for (int i = 2;i <= n;i++){ if (map[i].y - map[i-1].y <= abs(map[i].x - map[i-1].x)){ adde(map[i-1].cnt , map[i].cnt , map[i].y - map[i-1].y); adde(map[i].cnt , map[i-1].cnt , map[i].y - map[i-1].y); } } dijkstra(1); cout<<dis <<endl; return 0; }
相关文章推荐
- 循环队列+堆优化dijkstra最短路 BZOJ 4152: [AMPPZ2014]The Captain
- BZOJ 4152 The Captain (Dijkstra 堆优化)
- BZOJ 4152: [AMPPZ2014]The Captain(最短路)
- BZOJ 4152: [AMPPZ2014]The Captain( 最短路 )
- BZOJ 4152: [AMPPZ2014]The Captain 分层图最短路
- BZOJ[4152][AMPPZ2014]The Captain Dijkstra
- BZOJ 4152 [AMPPZ2014]The Captain 最短路题解
- BZOJ 3040 最短路(road) 堆优化Dijkstra
- 【Dijkstra堆优化】【BZOJ 3040】 最短路(road)
- 【BZOJ】【4152】【AMPZZ2014】The Captain
- BZOJ_1614_ [Usaco2007_Jan]_Telephone_Lines_架设电话线_(二分+最短路_Dijkstra/Spfa)
- 【最短路】【Heap-Dijkstra】【分层图】bzoj2662 [BeiJing wc2012]冻结
- [bzoj1975][Sdoi2010]魔法猪学院 k短路 dijkstra
- BZOJ 2292: 【POJ Challenge 】永远挑战 最短路 dijkstra+heap
- BZOJ-4152-最短路
- Bzoj 2763: [JLOI2011]飞行路线 dijkstra,堆,最短路,分层图
- Bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路 dijkstra,堆,A*,次短路
- 【平面图】【最小割】【最短路】【Heap-Dijkstra】bzoj1001 [BeiJing2006]狼抓兔子
- bzoj 4152 最短路SPFA
- BZOJ 3040: 最短路(road) [Dijkstra + pb_ds]