zoukankan      html  css  js  c++  java
  • 灾后重建

     

    题面

    给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的。并给出第i个村庄重建完成的时间ti​,你可以认为是同时开始重建并在第ti​天重建完成,并且在当天即可通车。若ti为则说明地震未对此地区造成损坏,一开始就可以通车。之后有Q个询问(x,y,t),对于每个询问你要回答在第t天,从村庄x到村庄y的最短路径长度为多少。如果无法找到从x村庄到y村庄的路径,经过若干个已重建完成的村庄,或者村庄x或村庄y在第t天仍未重建完成 ,则需要返回-1。

    思路:

    Floyd的理解

    for (int k=0;k<n;k++)
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                if (f[i][j] > f[i][k] + f[k][j])
                      f[i][j] = f[j][i] = f[i][k] + f[k][j];

    这段代码的基本思想就是:最开始只允许经过1号顶点进行中转,接下来只允许经过1和2号顶点进行中转……允许经过1~n号所有顶点进行中转,求任意两点之间的最短路程。用一句话概括就是:从i号顶点到j号顶点只经过前k号点的最短路程。

    (仔细理解这段话,它揭露了这个算法的本质并为本题提供了很好的方法)

    到这里我们已经知道,Floyd算法就是一个利用其它点进行中转来求最短路的步骤。

    而我们再回头看题意:

    所有的边全部给出,按照时间顺序更新每一个可用的点(即修建好村庄),对于每个时间点进行两点之间询问,求对于目前建设的所有村庄来说任意两点之间的最短路

    不正好就是Floyd算法中使用前k个节点更新最短路的思维吗?

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=210;
     4 int a[N],f[N][N],n,m,q,k,u,v,w,t;
     5 void fun(int k) {
     6     for (int i = 0; i < n; i++) {
     7         for (int j = 0; j < n; j++) {
     8             if (f[i][j] > f[i][k] + f[k][j]) {
     9                 f[i][j] = f[j][i] = f[i][k] + f[k][j];
    10             }
    11         }
    12     }
    13 }
    14 int main() {
    15     scanf("%d%d", &n, &m);
    16     for (int i = 0; i < n; i++) {
    17         scanf("%d", &a[i]);
    18     }
    19     memset(f, 0x3f3f3f3f, sizeof(f));
    20     for (int i = 0; i < n; i++) {
    21         f[i][i] = 0;
    22     }
    23     for (int i = 1; i <= m; i++) {
    24         int u, v, w;
    25         scanf("%d%d%d", &u, &v, &w);
    26         f[u][v] = f[v][u] = w;
    27     }
    28     scanf("%d", &q);
    29     while (q--) {
    30         scanf("%d%d%d", &u, &v, &t);
    31         while (a[k] <= t && k < n) {
    32             fun(k);
    33             k++;
    34         }
    35         if (a[u] > t || a[v] > t) {
    36             printf("-1
    ");
    37         } else {
    38             if (f[u][v] == 0x3f3f3f3f) {
    39                 printf("-1
    ");
    40             } else {
    41                 printf("%d
    ", f[u][v]);
    42             }
    43         }
    44     }
    45     return 0;
    46 }
    View Code
  • 相关阅读:
    dtoi2680「SDOI2016」生成魔咒
    dtoi2679「SDOI2016」游戏
    dtoi2678「SDOI2016」数字配对
    dtoi2677「SDOI2016」储能表
    dtoi4545「HNOI2016」树
    dtoi4543「HNOI2016」最小公倍数
    dtoi4544「HNOI2016」网络
    dtoi4548「HNOI2016」大数
    ts定义数组对象
    RN项目ios本地模拟机无法加载本地图片的解决方案
  • 原文地址:https://www.cnblogs.com/Accpted/p/11185722.html
Copyright © 2011-2022 走看看