题目链接:
https://vjudge.net/problem/POJ-1122
题目大意:
给出矩阵,矩阵中每个元素tij表示从第i个交叉路口到第j个交叉路口所需时间,若tij为-1则表示两交叉路口之间没有直接路径,再给出火警位置所在的交叉路口 和 一个或多个消防站所处的交叉路口位置。输出要求按消防站到火警位置所需时间从小到大排列,输出信息包括消防站位置(初始位置),火警位置(目标位置),所需时间,最短路径上每个交叉路口。
思路:
由于求的是其他点到某一点的最短路,所以反向建图,然后用dijkstra求出这点到其他点的最短路即可。求出来的就是其他点到这点的最短路,还需要保存路径。输入输出有格式要求,详细看代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #include<stack> 8 #include<map> 9 #include<set> 10 #include<sstream> 11 #define MEM(a, b) memset(a, b, sizeof(a)); 12 using namespace std; 13 typedef long long ll; 14 const int maxn = 50 + 10; 15 const int INF = 0x3f3f3f3f; 16 int T, n, m, cases, tot; 17 int Map[maxn][maxn], d[maxn], path[maxn]; 18 bool v[maxn]; 19 struct node 20 { 21 int id, time; 22 bool operator < (const node& a)const 23 { 24 return time < a.time; 25 } 26 }a[maxn]; 27 void dijkstra(int u) 28 { 29 for(int i = 1; i <= n; i++)d[i] = INF; 30 d[u] = 0; 31 memset(path, -1, sizeof(path)); 32 memset(v, 0, sizeof(v)); 33 for(int i = 0; i < n; i++) 34 { 35 int x, m = INF; 36 for(int i = 1; i <= n; i++)if(!v[i] && m > d[i])m = d[x = i]; 37 v[x] = 1; 38 for(int i = 1; i <= n; i++) 39 { 40 if(!v[i] && d[i] > d[x] + Map[x][i]) 41 { 42 d[i] = d[x] + Map[x][i]; 43 path[i] = x; 44 } 45 } 46 } 47 } 48 int main() 49 { 50 cin >> n; 51 int tot = 0; 52 for(int i = 1; i <= n; i++) 53 { 54 for(int j = 1; j <= n; j++) 55 { 56 cin >> Map[i][j]; 57 if(Map[i][j] == -1)Map[i][j] = INF; 58 } 59 } 60 for(int i = 1; i <= n; i++) 61 { 62 for(int j = i + 1; j <= n; j++)swap(Map[i][j], Map[j][i]); 63 } 64 string s; 65 int u, v; 66 cin >> u; 67 while(cin >> v)a[tot++].id = v; 68 dijkstra(u); 69 for(int i = 0; i < tot; i++) 70 { 71 a[i].time = d[a[i].id]; 72 } 73 sort(a, a + tot); 74 printf("Org Dest Time Path "); 75 for(int i = 0; i < tot; i++) 76 { 77 printf("%d %d %d ", a[i].id, u, a[i].time); 78 int x = a[i].id; 79 while(x != -1) 80 { 81 printf("%d ", x); 82 x = path[x]; 83 } 84 printf(" "); 85 } 86 return 0; 87 }