【堆优化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 }