1. 程式人生 > >1377:最優乘車

1377:最優乘車

旅遊景點 默認 方案 過程 eof 依次 style int 直接

【題目描述】

    H城是一個旅遊勝地,每年都有成千上萬的人前來觀光。為方便遊客,巴士公司在各個旅遊景點及賓館,飯店等地都設置了巴士站並開通了一些單程巴士線路。每條單程巴士線路從某個巴士站出發,依次途經若幹個巴士站,最終到達終點巴士站。一名旅客最近到H城旅遊,他很想去S公園遊玩,但如果從他所在的飯店沒有一路巴士可以直接到達S公園,則他可能要先乘某一路巴士坐幾站,再下來換乘同一站臺的另一路巴士, 這樣換乘幾次後到達S公園。現在用整數1,2,…N 給H城的所有的巴士站編號,約定這名旅客所在飯店的巴士站編號為1,S公園巴士站的編號為N。寫一個程序,幫助這名旅客尋找一個最優乘車方案,使他在從飯店乘車到S公園的過程中換車的次數最少。

【題目鏈接】

    http://ybt.ssoier.cn:8088/problem_show.php?pid=1377

【算法】

    最初建圖想的是同一線路相鄰點路徑權值為0,不同線路+1,發現很不好做,因為不同線路轉換情況太多。事實上,若把同一線路先到達的點和後到達的點間權值記為1,表示在後到達的點處更換線路,最後-1是因為最後一步不用換線路已經到了。然後用floyd就過了。

【一點思考】

    主要是如何建圖,這道題建的圖中,點表示的不是單一線路中的車站而是類似現實意義中的車站可以到達經過的任一線路,而邊權值為1表示默認會換線路。

【代碼】

 1 #include <bits/stdc++.h>
 2
using namespace std; 3 char s[1100]; 4 int n,m,a; 5 int G[510][510]; 6 int main() 7 { 8 memset(G,0x3f,sizeof(G)); 9 scanf("%d%d\n",&m,&n); 10 for(int i=1;i<=m;i++) { 11 vector<int> tmp; 12 gets(s+1); 13 for(int j=1;j<=strlen(s+1);j++) { 14 int
cur=0; 15 while(isdigit(s[j])) { 16 cur=cur*10+s[j]-0; 17 j++; 18 } 19 tmp.push_back(cur); 20 } 21 for(int j=0;j<tmp.size();j++) { 22 for(int k=j+1;k<tmp.size();k++) { 23 G[tmp[j]][tmp[k]]=1; 24 } 25 } 26 } 27 for(int k=1;k<=n;k++) 28 for(int i=1;i<=n;i++) 29 for(int j=1;j<=n;j++) 30 G[i][j]=min(G[i][j],G[i][k]+G[k][j]); 31 if(G[1][n]>1e7) puts("NO"); 32 else printf("%d\n",G[1][n]-1); 33 return 0; 34 }

1377:最優乘車