1. 程式人生 > >【POJ 2502】Subway(最短路dij)

【POJ 2502】Subway(最短路dij)

Description

You have just moved from a quiet Waterloo neighbourhood to a big, noisy city. Instead of getting to ride your bike to school every day, you now get to walk and take the subway. Because you don’t want to be late for class, you want to know how long it will take you to get to school.
You walk at a speed of 10 km/h. The subway travels at 40 km/h. Assume that you are lucky, and whenever you arrive at a subway station, a train is there that you can board immediately. You may get on and off the subway any number of times, and you may switch between different subway lines if you wish. All subway lines go in both directions.

Input

Input consists of the x,y coordinates of your home and your school, followed by specifications of several subway lines. Each subway line consists of the non-negative integer x,y coordinates of each stop on the line, in order. You may assume the subway runs in a straight line between adjacent stops, and the coordinates represent an integral number of metres. Each line has at least two stops. The end of each subway line is followed by the dummy coordinate pair -1,-1. In total there are at most 200 subway stops in the city.

Output

Output is the number of minutes it will take you to get to school, rounded to the nearest minute, taking the fastest route.

Sample Input

0 0 10000 1000
0 200 5000 200 7000 200 -1 -1
2000 600 5000 600 10000 600 -1 -1

Sample Output

21

題目大意

題目大意就是說一個人走路的時速是10km/h,坐動車的話是40km/h,現在問你從(x,y)到達(posx,posy)需要花費的最小時間(單位為分鐘)。每當輸入-1 -1時表示一條線路的所有站點輸入結束。

思路

這題主要難在輸入的處理,需要計算兩點間的距離,同時又要注意只有處在同一條線路上的相鄰動車站之間才能到達,在建邊的時候要特別注意這一點。對於多組輸入可以用while來實現,單位可以在計算前先統一轉換。這些處理好後就是一個dij的模版題了。因為對於這種卡輸入的題我表示並不想做,所以就網上copy了一份程式碼,大家可以參考。

程式碼

#include<stdio.h>
#include<math.h>
#include<string.h>

#define min(a,b) (a<b?a:b)
#define INF 0x3f3f3f3f
#define MAXV 205

typedef struct
{
    int x,y;
}Point;
double map[MAXV][MAXV],d[MAXV];
int v[MAXV],n;
Point point[MAXV],a;

int exist(Point t);
float distance(Point a,Point b);
void Dijkstra();

int main()
{
    int subway[MAXV],k;//subway表示地鐵上的第n個點
    for(int i=1;i<=MAXV;i++)
        for(int j=1;j<=MAXV;j++)
            map[i][j]=(i==j?0:INF);
    scanf("%d%d%d%d",&point[1].x,&point[1].y,&point[2].x,&point[2].y);
    n=2;
    while(~scanf("%d%d",&a.x,&a.y))
    {
        k=0;
        subway[k++]=exist(a);
        while(scanf("%d%d",&a.x,&a.y)&&a.x!=-1&&a.y!=-1)
            subway[k++]=exist(a);
        for(int i=1;i<k;i++)
            map[subway[i]][subway[i-1]]=map[subway[i-1]][subway[i]]=distance(point[subway[i]],point[subway[i-1]])*60.0/40000.0;//40 km/h= 40000/60 m/min
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            map[i][j]=map[j][i]=min(map[i][j],distance(point[i],point[j])*60.0/10000.0);//10 km/h= 10000/60 m/min
    Dijkstra();
    return 0;
}
int exist(Point t)//返回值為第幾個點 
{
    int i;
    for(i=1;i<=n;i++)
        if(t.x==point[i].x&&t.y==point[i].y) 
            break;
    if(i==n+1)
        point[++n]=t;
    return i;
}
float distance(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void Dijkstra()
{
    for(int i=1;i<=n;i++)
        d[i]=map[1][i];
    memset(v,0,sizeof(v));
    for(int i=1;i<=n;i++)
    {
        int x,m=INF;
        for(int y=1;y<=n;y++)
            if(!v[y]&&d[y]<m)
                m=d[x=y];
        v[x]=1;
        for(int y=1;y<=n;y++)
            d[y]=min(d[y],d[x]+map[x][y]);
    }
    printf("%d\n",int(d[2]+0.5));
}