bzoj4152 [AMPPZ2014]The Captain
最短路,先将x排序,然后把排序后权值相邻的点连边,再把y排序,也把权值相邻的点连边,求一遍1到n的最短路就好啦。
代码
1 #include<cstdio> 2 #include<queue> 3 #include<algorithm> 4 #define mp make_pair 5 #define fi first 6 #define sc second 7 #define N 1000000 8 using namespace std; 9 typedef long long ll; 10 typedef pair<int,int> P; 11 int n,i,dp,p[N],pre[N],tt[N],ww[N],flag[N]; 12 int dis[N]; 13 priority_queue<P,vector<P>,greater<P> > Q; 14 struct g{ 15 int a,b,id; 16 }v[N]; 17 bool cmp1(g u,g v) 18 { 19 return u.a<v.a; 20 } 21 bool cmp2(g u,g v) 22 { 23 return u.b<v.b; 24 } 25 26 void link(int x,int y,int z) 27 { 28 dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;ww[dp]=z; 29 } 30 long long ans,f[N],sum[N]; 31 int main() 32 { 33 scanf("%d",&n); 34 for (i=1;i<=n;i++) 35 scanf("%d%d",&v[i].a,&v[i].b),v[i].id=i; 36 sort(v+1,v+1+n,cmp1); 37 for (i=1;i<n;i++) 38 { 39 link(v[i].id,v[i+1].id,abs(v[i].a-v[i+1].a)); 40 link(v[i+1].id,v[i].id,abs(v[i].a-v[i+1].a)); 41 } 42 sort(v+1,v+1+n,cmp2); 43 for (i=1;i<n;i++) 44 { 45 link(v[i].id,v[i+1].id,abs(v[i].b-v[i+1].b)); 46 link(v[i+1].id,v[i].id,abs(v[i].b-v[i+1].b)); 47 } 48 int inf=1000000000; 49 for (i=2;i<=n;i++) dis[i]=inf; 50 Q.push(mp(0,1)); 51 52 while (!Q.empty()) 53 { 54 P x=Q.top();Q.pop(); 55 if (x.fi!=dis[x.sc]) continue; 56 i=p[x.sc]; 57 while (i) 58 { 59 if (dis[x.sc]+ww[i]<dis[tt[i]]) 60 { 61 dis[tt[i]]=dis[x.sc]+ww[i]; 62 Q.push(mp(dis[tt[i]],tt[i])); 63 } 64 i=pre[i]; 65 } 66 } 67 printf("%d\n",dis[n]); 68 }