【堆优化Dijkstra】BZOJ4152- [AMPPZ2014]The Captain

【题目大意】

给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。

【思路】

按照某维坐标排序,相邻两个点在这一维度上的差值最小,所以两两连边,长度为这一维度上的差值(不用考虑另外一维度的,就算另外一维度的更小,在连另外一维度的时候也能够抵达)。然后跑最短路即可。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 typedef long long ll;
 9 const ll INF=1e15;
10 const int MAXN=200000+50;
11 struct node
12 {
13     int x,y,id;
14 }p[MAXN];
15 struct edge
16 {
17     int to,len;
18 };
19 vector<edge> E[MAXN];
20 int n;
21 priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > que;
22 ll dis[MAXN];int vis[MAXN];
23 
24 bool cmpx(node a,node b){return (a.x<b.x);}
25 bool cmpy(node a,node b){return (a.y<b.y);}
26 
27 void addedge(int u,int v,int w)
28 {
29     E[u].push_back((edge){v,w});
30     E[v].push_back((edge){u,w});
31 }
32 
33 void init()
34 {
35     scanf("%d",&n);
36     for (int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y),p[i].id=i;
37     sort(p+1,p+n+1,cmpx);
38     for (int i=1;i<n;i++) addedge(p[i].id,p[i+1].id,p[i+1].x-p[i].x);
39     sort(p+1,p+n+1,cmpy);
40     for (int i=1;i<n;i++) addedge(p[i].id,p[i+1].id,p[i+1].y-p[i].y);
41 
42 }
43 
44 void solve()
45 {            
46     for (int i=1;i<=n;i++) vis[i]=0,dis[i]=INF;
47     dis[1]=0;
48     que.push(make_pair<ll,int>(0,1));
49     while (!que.empty())
50     {
51         int head=que.top().second;que.pop();
52         vis[head]=1;
53         for (int i=0;i<E[head].size();i++)
54         {
55             edge now=E[head][i];
56             if (!vis[now.to] && dis[now.to]>dis[head]+(ll)now.len)
57             {
58                 dis[now.to]=dis[head]+(ll)now.len;
59                 que.push(make_pair<ll,int>(dis[now.to],now.to));
60             }
61         }
62     }
63     printf("%lld",dis[n]);
64 }
65 
66 int main()
67 {
68     init();
69     solve();
70     return 0;
71 }

 

posted @ 2016-11-12 20:29  iiyiyi  阅读(532)  评论(0编辑  收藏  举报