1. 程式人生 > >Poj 2502 Subway(最短路)

Poj 2502 Subway(最短路)

題意:題意好理解,一個人步行的速度為每小時10公里,坐地鐵的速度為40公里每小時。首先給出你兩個點,分別是起點和終點。然後給出若干條鐵路,每個鐵路上至少有兩個站點(也就是這條起點和終點),然後-1,-1為結束。問你從起點到終點最短需要多長時間。

題解:如何建圖是一個問題。資料較小用臨界矩陣來存圖,我們可以把所有的站點,和起點終點當作圖中的點來存圖。存起來比較麻煩,需要存每個站點的時間,還有人到每個站點的時間。明白了要存什麼,就看具體程式碼實現。spfa求最短路。

#include<cstring>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;

const int N = 30005;
const double INF = 1e9+0.0;

struct node{
	int x;
	int y;
}p[N];

int cnt,sum;
double dis[N];
int vis[N];
double ma[250][250];
double walk(node a,node b){
	return sqrt((double)(a.x-b.x) * (double)(a.x - b.x) + (double)(a.y - b.y) * (double)(a.y - b.y)) * 60.0 /10000.0;
}
double subway(node a,node b){
	return sqrt((double)(a.x-b.x) * (double)(a.x - b.x) + (double)(a.y - b.y) * (double)(a.y - b.y)) * 60.0 /40000.0;
}

void spfa(){ 
	memset(vis,0,sizeof(vis));
	for(int i = 0 ; i < 240 ; i ++)
		dis[i] = INF ;
	queue <int> q;
	dis[1] = 0;
	vis[1] = 1;
	q.push(1);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		vis[u] = 0;
		for(int i = 1; i < cnt ; i++){
			if(dis[i] > dis[u] + ma[u][i]){
				dis[i] = dis[u] + ma[u][i];
				if(!vis[i]){
					vis[i] = 1;
					q.push(i);
				}
			} 
		}
	}
}
int main(){
	cnt = 3;
	sum = 0;
	for(int i = 0 ; i < 240 ; i ++)  // 初始化 
		for(int j = 0  ;j < 240 ; j++)
			ma[i][j] = i == j ? 0.0 : INF;
	scanf("%d%d%d%d",&p[1].x,&p[1].y,&p[2].x,&p[2].y);  //輸入起點和終點 
	ma[2][1] = ma[1][2] = walk(p[1],p[2]);   // 把起點當作第一個點 ,把終點當作第二個點 
	while(~scanf("%d%d",&p[cnt].x,&p[cnt].y)){  // 輸入若干鐵路。 
		if(p[cnt].x == -1 && p[cnt].y == -1){  // 結束標識 
			sum = 0 ;  // 當sum=0 表示現在輸入一條全新的鐵路。 
			continue;
		}
		for(int i = 1; i < cnt - sum ; i ++)  // 計算人到每個站點的時間 
			ma[i][cnt] = ma[cnt][i] = walk(p[cnt],p[i]);
		if(sum) // 若sum = 1 則,計算這條鐵路到上個站點的時間。 若sum=0就不計算。很精髓 
			ma[cnt][cnt-1] = ma[cnt - 1][cnt] = subway(p[cnt],p[cnt-1]);
		cnt ++;
		sum = 1;
	}
//	for(int i = 1 ; i < cnt ; i++){
//		for(int j = 1; j < cnt ;j ++)
//			cout << ma[i][j] << " ";
//		cout << endl;
//	}
	spfa();
	printf("%d\n",(int)(dis[2] + 0.5));
	return 0;
}