BZOJ 2834(回家的路-分层图最短路)

2834: 回家的路

Time Limit: 10 Sec   Memory Limit: 128 MB
Submit: 15   Solved: 11
[ Submit][ Status][ Discuss]

Description

Input

BZOJ 2834(回家的路-分层图最短路)_第1张图片

Output

Sample Input

2 1
1 2
1 1 2 2

Sample Output

5

HINT

N<=20000,M<=100000

Source


分层图最短路

假设地铁站有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;
}




你可能感兴趣的:(BZOJ 2834(回家的路-分层图最短路))