1. 程式人生 > >Dijkstra--POJ 2502 Subway(求出所有路徑再求最短路徑)

Dijkstra--POJ 2502 Subway(求出所有路徑再求最短路徑)

題意: 你從家往學校趕,可以用步行和乘坐地鐵這兩種方式,步行速度為10km/h,乘坐地鐵的速度為40KM/h。輸入資料的第一行資料會給你起點和終點的x和y的座標。然後會給你數目不超過200的雙向地鐵線路的站點,你可以從一個站點乘坐地鐵到下一個站點,你可以在同一線路上乘坐地鐵經過不同的站點,在不同線路的站點之間,你只能用步行的方式。讓你求利用你可以利用的方式,求解到校花費的最短時間。 思路: 基礎最短路徑問題,Dijkstra演算法可以解決。需要特別注意以下輸入資料的方式,這道題目沒有很明顯的輸入結束標誌,要用scanf()!= EOF來進行判斷。然後把圖的資訊存入 map數組裡面,當i到j在一條鐵路線路上的時候,用它的距離除以40000來求解時間並存入map[i][j]中,map其他的位置儲存不行的時間,然後套用模板直接求解最短路徑就可以了。

#include<iostream>
#include<cmath>
#include<string>
#include<cstdlib>
#include<algorithm>
using namespace std;

const double INF=100000000.0;

struct Point
{
       double x;
       double y;
}p[205];

bool visited[205];
int n;
double d[205];
double map[205][205];
double getLen(Point p1,Point p2){
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
void Dijkstra(){
	int i,j,u;
	double temp;
	visited[0]=true;
	    for(i=0;i<n;i++)
	       d[i]=map[0][i];
	    for(i=1;i<n;i++)
	    {
	         temp=INF;
	         for(j=0;j<n;j++)
	           if(!visited[j]&&d[j]<temp)
	           {
	               temp=d[j];
	               u=j;
	           }
	         visited[u]=true;
	         for(j=0;j<n;j++)
	           if(!visited[j])
	           {
	              temp=d[u]+map[u][j];
	              if(temp<d[j])
	                  d[j]=temp;
	           }
	    }
}
int main()
{
	int i,j;
	double temp;
    bool flag=false;
    scanf("%lf%lf%lf%lf",&p[0].x,&p[0].y,&p[1].x,&p[1].y);                                                          //起始位置和目的地座標
    n=2;
    memset(map,0,sizeof(map));
    while(~scanf("%lf%lf",&p[n].x,&p[n].y))
    {
        if(p[n].x==-1&&p[n].y==-1)
        {
            flag=false;
            continue;
        }
        if(flag)  //有效的處理了只輸入第一個點時不產生線段
        {
            temp=getLen(p[n],p[n-1])/40000.0;          //儲存的是時間(小時),地鐵的速度是40km/h
            map[n][n-1]=map[n-1][n]=temp;
        }
        n++;
        flag=true;
    }
    //得到所有步行段的距離  一共n(2+(n-2))個點
    for(i=0;i<n;i++)                                                                                               //計算需要步行的所用的時間
      for(j=0;j<n;j++)
        if(i!=j&&map[i][j]==0.0)//初始是0.0(步行段)
           map[i][j]=map[j][i]=getLen(p[i],p[j])/10000.0;     //步行的速度是10km/h

    memset(visited,0,sizeof(visited));
    //Dijkstra演算法求解最短路
    Dijkstra();                                                                                              //題目所要求的單位是分鐘
    printf("%0.0lf\n",60.0*d[1]);
    return 0;
}