zoukankan      html  css  js  c++  java
  • poj1122 FDNY to the Rescue!(dij+反向建图+输出路径)

    题目链接:poj1122 FDNY to the Rescue!

    题意:给出矩阵,矩阵中每个元素tij表示从第i个交叉路口到第j个交叉路口所需时间,若tij为-1则表示两交叉路口之间没有直接路径,再给出火警位置所在的交叉路口 和 一个或多个消防站所处的交叉路口位置。输出要求按消防站到火警位置所需时间从小到大排列,输出信息包括消防站位置(初始位置),火警位置(目标位置),所需时间,最短路径上每个交叉路口。

    题解:反向建图,从火警位置求一次最短路,求最短路时记录路径,按时间从小到大输出。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define CLR(a,b) memset((a),(b),sizeof((a)))
     5 using namespace std;
     6 
     7 const int inf = 0x3f3f3f3f;
     8 const int N = 21;
     9 int n, fire;
    10 int g[N][N];//邻接矩阵存图
    11 int s[N], d[N];
    12 int path[N];//表示v0到vi最短路径顶点vi的前一个顶点序号
    13 int shortest[N];//存储最短路径上的各个顶点序号
    14 struct node{
    15     int u, v, t;
    16 }a[N];
    17 int cmp(node a, node b){
    18     return a.t < b.t;
    19 }
    20 void dij(){
    21     int i, j, k;
    22     CLR(s, 0);
    23     for(i = 1; i <= n; ++i){
    24         d[i] = g[fire][i];
    25         if(i != fire)
    26             path[i] = fire;
    27         else
    28             path[i] = -1;
    29     }
    30     s[fire] = 1;
    31     d[fire] = 0;
    32     for(i = 0; i < n-1; ++i){
    33         int mi = inf, u = 0;
    34         for(j = 1; j <= n ; ++j){
    35             if(!s[j] && d[j] < mi){
    36                 u = j; mi = d[j];
    37             }
    38         }
    39         s[u] = 1;
    40         for(k = 1; k <= n; ++k){
    41             if(!s[k] && d[u] + g[u][k] < d[k]){
    42                 d[k] = d[u] + g[u][k];
    43                 path[k] = u;
    44             }
    45         }
    46     }
    47 }
    48 int main(){
    49     int i, j, x, cnt;
    50     scanf("%d", &n);
    51     for(i = 1; i <= n; ++i){//边反向存储
    52         for(j = 1; j <= n; ++j){
    53             scanf("%d", &x);
    54             if(x == -1)
    55                 g[j][i] = inf;
    56             else
    57                 g[j][i] = x;
    58         }
    59     }
    60     scanf("%d", &fire);
    61     dij();
    62     cnt = 0;
    63     while(scanf("%d", &x) == 1){
    64         a[cnt].u = x;
    65         a[cnt].v = fire;
    66         a[cnt++].t = d[x];
    67     }
    68     sort(a, a+cnt, cmp);
    69     printf("Org	Dest	Time	Path
    ");
    70     for(i = 0; i < cnt; ++i){
    71         printf("%d	%d	%d", a[i].u, a[i].v, a[i].t);
    72         CLR(shortest, 0);
    73         int k = 0;//表示shortest数组中最后一个元素的下标
    74         shortest[k] = a[i].u;
    75         while(path[shortest[k]] != -1){
    76             k++;
    77             shortest[k] = path[shortest[k-1]];
    78         }
    79         for(j = 0; j <= k; ++j) //倒向追踪,但是反向建图,因此正向输出
    80             printf("	%d", shortest[j]);
    81         puts("");
    82     }
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    [DB] 数据库的连接
    JS leetcode 翻转字符串里的单词 题解分析
    JS leetcode 拥有最多糖果的孩子 题解分析,六一快乐。
    JS leetcode 搜索插入位置 题解分析
    JS leetcode 杨辉三角Ⅱ 题解分析
    JS leetcode 寻找数组的中心索引 题解分析
    JS leetcode 移除元素 题解分析
    JS leetcode 最大连续1的个数 题解分析
    JS leetcode 两数之和 II
    JS leetcode 反转字符串 题解分析
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/5931217.html
Copyright © 2011-2022 走看看