题目大意:
给定N个城市之间每条线路的花费,及经过第 i 个城市的税收费用,求从 start 到 ends 城市使用的总费用。
题目测试数据与数据范围:
5 0 3 22 -1 4 3 0 5 -1 -1 22 5 0 9 20 -1 -1 9 0 4 4 -1 20 4 0 5 17 8 3 1 1 3 3 5 2 4 -1 -1 0
题目分折:From 1 to 3 : Path: 1-->5-->4-->3 Total cost : 21 From 3 to 5 : Path: 3-->4-->5 Total cost : 16 From 2 to 4 : Path: 2-->1-->5-->4 Total cost : 17
此题为多源最短路径问题,并且要记录路径,所以在 运用 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]);
}
}
}
伟大的梦想成就伟大的人,从细节做好,从点点滴滴做好,从认真做好。