N<=20000,M<=100000
分层图最短路
假设地铁站有2程,一层横向铁路,一层纵向铁路
然后……就是普通的最短路了
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define MAXN (200000+10) #define MAXM (1000000+10) #define INF (2139062143) int n,m; struct node { int x,y,no; }a[MAXM]; bool cmp(node a,node b) {return a.x==b.x?a.y<b.y:a.x<b.x;} bool cmp2(node a,node b) {return a.y==b.y?a.x<b.x:a.y<b.y;} int edge[MAXM*4],next[MAXM*4],weight[MAXM*4],pre[MAXM],size=0; void addedge(int u,int v,int w) { edge[++size]=v; weight[size]=w; next[size]=pre[u]; pre[u]=size; } void addedge2(int u,int v,int w){addedge(u,v,w),addedge(v,u,w);} int q[MAXM*8],d[MAXM]; void SPFA(int s) { memset(d,127,sizeof(d)); d[s]=0;q[1]=s; int head=1,tail=1; while (head<=tail) { int now=q[head]; Forp(now) { int &v=edge[p]; if (d[now]+weight[p]<d[v]) { d[v]=d[now]+weight[p]; q[++tail]=v; } } head++; } } int main() { //freopen("bzoj2834.in","r",stdin); scanf("%d%d",&n,&m); For(i,m+2) scanf("%d%d",&a[i].x,&a[i].y),a[i].no=i; sort(a+1,a+1+m+2,cmp); For(i,m+1) if (a[i].x==a[i+1].x) addedge2(a[i].no,a[i+1].no,2*(a[i+1].y-a[i].y)); sort(a+1,a+1+m+2,cmp2); For(i,m+1) if (a[i].y==a[i+1].y) addedge2(a[i].no+m+2,a[i+1].no+m+2,2*(a[i+1].x-a[i].x)); For(i,m) addedge2(i,i+m+2,1); addedge2(m+1,m+1+m+2,0);addedge2(m+2,m+2+m+2,0); SPFA(m+1); if (d[m+2]==INF) puts("-1"); else cout<<d[m+2]<<endl; return 0; }