Poj 2502 Subway(最短路)
阿新 • • 發佈:2018-12-22
題意:題意好理解,一個人步行的速度為每小時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; }