題目大意:
給定N個城市之間每條線路的花費,及經過第 i 個城市的稅收費用,求從 start 到 ends 城市使用的總費用。
題目測試數據與數據範圍:
此題爲多源最短路徑問題,並且要記錄路徑,所以在 運用 Floyd() 算法的基礎上記錄路徑即可,而且要求字典序要儘可能的小,所以在路徑桐的情況下一定要儘可能的經過較小的。
小樂一下:
用我們的心認真去做一些事情
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1385
代碼:
#include<cstdio>
#include<cstring>
const int maxn = 100;
const int INF = 1000000;
int n,dp[maxn][maxn],path[maxn][maxn],tax[maxn];
void floyd(){
int i,j,k;
for(i = 1;i<=n;i++){
for(j = 1;j<=n;j++) path[i][j] = j; //初始時設i點的下一個點是j點。
}
for(k = 1;k<=n;k++){
for(i = 1;i<=n;i++){
for(j = 1;j<=n;j++){
int temp = dp[i][k] + dp[k][j] + tax[k];
if(temp<dp[i][j]){
dp[i][j] = temp;
path[i][j] = path[i][k]; //經過了k點。
}
if(temp == dp[i][j]){
if(path[i][j]>path[i][k]) path[i][j] = path[i][k]; //相同路徑情況下,要字典序儘量小。
}
}
}
}
}
int main(){
int i,j;
int costs;
int a,b;
while(scanf("%d",&n)!=EOF,n){
for(i = 1;i<=n;i++){
for(j = 1;j<=n;j++){
scanf("%d",&costs);
if(costs == -1)dp[i][j] = INF;
else dp[i][j] = costs;
}
}
for(i = 1;i<=n;i++) scanf("%d",&tax[i]);
floyd();
while(scanf("%d%d",&a,&b)!=EOF){
if(a==-1 && b==-1) break;
printf("From %d to %d :\n",a,b);
printf("Path: %d",a);
int temp = a;
while(temp != b){ //路徑輸出時,依次輸出a的下一個點,再輸出下一個的下一個點。
printf("-->%d",path[temp][b]);
temp = path[temp][b];
}
printf("\nTotal cost : %d\n\n",dp[a][b]);
}
}
}
偉大的夢想成就偉大的人,從細節做好,從點點滴滴做好,從認真做好。