题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1385
参考 http://blog.csdn.net/shuangde800/article/details/8075165
题目大意:
有N个城市,然后直接给出这些城市之间的邻接矩阵,矩阵中-1代表那两个城市无道路相连,其他值代表路径长度。
如果一辆汽车经过某个城市,必须要交一定的钱(可能是过路费)。
现在要从a城到b城,花费为路径长度之和,再加上除起点与终点外所有城市的过路费之和。
求最小花费,如果有多条路经符合,则输出字典序最小的路径。
解析:
直接跑一边Floyd算法就好 用一个二维数组保存路径path[ i ][ j ]表示第i个节点到第j个节点经过的第一个点(例如1->2->5->4,path[1][4]=2,path[2][4]=5,path[5][4]=5)
AC代码
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <iostream> 6 #include <sstream> 7 #include <algorithm> 8 #include <string> 9 #include <queue> 10 #include <map> 11 #include <vector> 12 using namespace std; 13 const int maxn = 10005; 14 const int maxm = 1e4+10; 15 const int inf = 0x3f3f3f3f; 16 const double epx = 1e-10; 17 typedef long long ll; 18 int n; 19 int w[maxn][maxn]; 20 int path[maxn][maxn]; 21 int tax[maxn]; 22 void init() 23 { 24 for(int i=0;i<=n;i++) 25 { 26 for(int j=0;j<=n;j++) 27 { 28 if(i!=j) 29 w[i][j]=inf; 30 else 31 w[i][j]=0; //自己到自己设为0 32 path[i][j]=j; //初始化为j 33 } 34 } 35 } 36 void Floyd() 37 { 38 for(int k=1;k<=n;k++) 39 for(int i=1;i<=n;i++) 40 for(int j=1;j<=n;j++) 41 if(w[i][k]!=inf&&w[k][j]!=inf) 42 { 43 int temp=w[i][k]+w[k][j]+tax[k]; //tax[]是过路费 44 if(w[i][j]>temp) //松弛操作的时候,顺带更新路径 45 { 46 w[i][j]=temp; 47 path[i][j]=path[i][k]; 48 } 49 else if(w[i][j]==temp&&path[i][j]>path[i][k])//字典序最小,不要求字典序的话可直接省略 50 { 51 path[i][j]=path[i][k]; 52 } 53 } 54 } 55 int main() 56 { 57 while(cin>>n&&n) 58 { 59 init(); 60 for(int i=1;i<=n;i++) 61 { 62 for(int j=1;j<=n;j++) 63 { 64 cin>>w[i][j]; 65 if(w[i][j]==-1) 66 w[i][j]=inf; 67 } 68 } 69 for(int i=1;i<=n;i++) 70 cin>>tax[i]; 71 Floyd(); 72 int s,e; 73 while(cin>>s>>e&&s!=-1&&e!=-1) 74 { 75 printf("From %d to %d :\n",s,e); 76 printf("Path: "); 77 int u=s; 78 printf("%d",u); //打印路径 79 while(u!=e) 80 { 81 printf("-->%d",path[u][e]); 82 u=path[u][e]; 83 } 84 printf("\n"); 85 printf("Total cost : %d\n\n",w[s][e]); 86 } 87 88 } 89 }