【bzoj4152: [AMPPZ2014]The Captain】最短路
生活随笔
收集整理的這篇文章主要介紹了
【bzoj4152: [AMPPZ2014]The Captain】最短路
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
4152: [AMPPZ2014]The Captain
Time Limit:?20 Sec??Memory Limit:?256 MBSubmit:?1459??Solved:?576
[Submit][Status][Discuss]
Description
給定平面上的n個點,定義(x1,y1)到(x2,y2)的費用為min(|x1-x2|,|y1-y2|),求從1號點走到n號點的最小費用。Input
第一行包含一個正整數n(2<=n<=200000),表示點數。 接下來n行,每行包含兩個整數x[i],y[i](0<=x[i],y[i]<=10^9),依次表示每個點的坐標。Output
一個整數,即最小費用。Sample Input
52 2
1 1
4 5
7 1
6 7
Sample Output
2HINT
Source
鳴謝Claris上傳
剛開始想著貪心,把邊按x和y分別排序,然后對于每個xi向后連6個(這里是貪心,因為如果是暴力的話把所有的邊都建出來,而我只是把相對較優的幾條邊建出來了)。然后跑最短路,這里跑spfa會掛,要跑dijkstra+堆優化。然后就過了。
后來仔細一想,發現正解就是我最貪心的情況:每個xi只向后連一個就好了,因為單單對于x來說,(x1,x3)=(x1,x2)+(x2,x3) (這里的x是排好序的,所以成立),所以對于min(|x1-x2|,|y1-y2|)是|x1-x2|,即是用x的差的絕對值來更新的話,我們用上述建邊方法就是最優的,同理可以用同樣的方法對y建邊。
所以分別按x和y排序,相鄰的點連邊,跑最短路就Ok了
#include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> #include<algorithm> #define Pa pair<int,int> #define N 200005 #define M (N*50*2) #define INF 1e9+7 using namespace std; int k,fir[N],x[N],y[N],dis[N],n,vis[N]; struct ha{int d,p; }a[N],b[N]; struct he{int r,c,nx; }A[M]; int abs(int x){if(x<0) return -x;return x; } bool cmp(ha a,ha b){return a.d<b.d; } void add(int l,int r,int c){k++;A[k].r=r;A[k].c=c;A[k].nx=fir[l];fir[l]=k; } /*queue<int>Q; int spfa(){for(int i=1;i<=n;i++)dis[i]=INF;dis[1]=0;Q.push(1);while(!Q.empty()){int u=Q.front();Q.pop();vis[u]=0;for(int i=fir[u];i!=-1;i=A[i].nx)if(dis[u]+A[i].c<dis[A[i].r]){dis[A[i].r]=dis[u]+A[i].c;if(!vis[A[i].r]){vis[A[i].r]=1;Q.push(A[i].r);}}}return dis[n]; }*/ int dij(int st,int ed){priority_queue<Pa,vector<Pa>,greater<Pa> >Q;for(int i=st;i<=ed;i++) dis[i]=INF; Q.push(make_pair(0,st));dis[st]=0;while(!Q.empty()){int u=Q.top().second;int Dis=Q.top().first;Q.pop();if(Dis>dis[u]) continue;for(int i=fir[u];i!=-1;i=A[i].nx)if(dis[u]+A[i].c<dis[A[i].r])dis[A[i].r]=dis[u]+A[i].c,Q.push(make_pair(dis[A[i].r],A[i].r));}return dis[ed]; } int main(){freopen("1.in","r",stdin);memset(fir,-1,sizeof(fir));scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d",&x[i],&y[i]);a[i].d=x[i],a[i].p=i;b[i].d=y[i],b[i].p=i;}sort(a+1,a+1+n,cmp);sort(b+1,b+1+n,cmp);for(int i=1;i<n;i++)for(int j=i+1;j<=i+1;j++)add(a[i].p,a[j].p,a[j].d-a[i].d),add(a[j].p,a[i].p,a[j].d-a[i].d);for(int i=1;i<n;i++)for(int j=i+1;j<=i+1;j++)add(b[i].p,b[j].p,b[j].d-b[i].d),add(b[j].p,b[i].p,b[j].d-b[i].d); // printf("%d\n",spfa());printf("%d\n",dij(1,n)); }總結
以上是生活随笔為你收集整理的【bzoj4152: [AMPPZ2014]The Captain】最短路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用HISTFILESIZE和HISTS
- 下一篇: MySQL单表数据量过大的处理方式经验