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算法一次直接求出各点间的最短路径
或用dijkstra算法在每次询问后求得单源最短路径
由于习惯性以为一次性求出要好,所以我用的floyd算法,仔细一想由于询问次数未知用dijkstra算法可能要好些。
//这是大神的代码,粘贴别人的 #include <iostream> #include <fstream> using namespace std; int const Max=1001; int a[Max][Max];//存放边的权值 int b[Max];//存放顶点的权值 int nex[Max][Max]; //next[i][j]用来保存i-->j的最短路径中i的最优后(即最近, int N; void floyd() //flyod算法求个顶点间的最短路径长度并记录路径 { int i,j,k,fee; for(i=1;i<=N;i++) for(j=1;j<=N;j++) nex[i][j]=j; for(k=1;k<=N;k++) { for(i=1;i<=N;i++) { if(i==k||a[i][k]==-1) continue; for(j=1;j<=N;j++) { if(a[k][j]==-1||j==k) continue; fee = a[i][k]+a[k][j]+b[k]; if(a[i][j]==-1||a[i][j]>fee) { a[i][j]=fee; nex[i][j]=nex[i][k]; } //选择字典序小的路径 else if(a[i][j]==fee) { if(nex[i][j]>nex[i][k]) nex[i][j]=nex[i][k]; } } } } } void path(int i, int j) //递归输出最短路径 { if(j==nex[i][j]) { printf("%d-->%d\n",i,j); } else { printf("%d-->",i); path(nex[i][j],j); } } int main() { int i, j; int A, B; while(cin>>N && N) { for(i=1; i<=N; i++) for(j=1; j<=N; j++) cin>>a[i][j]; for(i=1; i<=N; i++) cin>>b[i]; floyd(); while(cin>>A>>B && (A!=-1 || B!=-1)) { printf("From %d to %d :\n", A, B); if(A == B) printf("Path: %d\n", A); else { printf("Path: "); path(A, B); } printf("Total cost : %d\n\n", a[A][B]); } } return 0; }
//这是我的代码,实在不堪入目 #include<iostream> #define MAX 1001 using namespace std; int g[MAX][MAX]; int cost[MAX][MAX]; int path[MAX][MAX]; int way[MAX]; int city[MAX]; int n; void floyd() { int k,i,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { cost[i][j]=g[i][j]; path[i][j]=i; } } for(k=1;k<=n;k++) { for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { //打印路径!!!!!!!!!!!!!!!!!!!!! if(cost[i][j]!=-1&&cost[i][k]!=-1&&cost[k][j]!=-1&&cost[i][j]>cost[i][k]+cost[k][j]) { cost[i][j]=cost[i][k]+cost[k][j]+city[k]; path[i][j]=path[k][j]; } else if(cost[i][j]==-1&&cost[i][k]!=-1&&cost[k][j]!=-1) { cost[i][j]=cost[i][k]+cost[k][j]+city[k]; path[i][j]=path[k][j]; } } } } } int main() { int i,s,e,j,k; while(cin>>n) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%d",&g[i][j]); for(i=1;i<=n;i++) scanf("%d",&city[i]); floyd(); while(cin>>s>>e&&!(s==-1&&e==-1)) { k=0; way[k]=e; while(path[s][way[k]]!=s) { k++; way[k]=path[s][way[k-1]]; } k++; way[k]=s; cout<<"From "<<s<<" to "<<e<<" :"<<endl; cout<<"Path: "; for(i=k;i>0;i--) cout<<way[i]<<"-->"; cout<<way[i]<<endl; cout<<"Total cost : "<<cost[s][e]<<endl; } } return 0; }