zoukankan      html  css  js  c++  java
  • 【洛谷习题】灾后重建

    题目链接:https://www.luogu.org/problemnew/show/P1119


    暴力的做法很容易想到,对于每次询问,将修好的点加到图上,复杂度可以是O(mlogn*q),粗略算一下会炸。看到N<=200,忽然想到了Floyd,又想将询问保存,倒序处理,也就是每次删边,毫无疑问这是错误的。然后翻看dalao的博客,才意识到,原来Floyd是这样的!Floyd的原理是动态规划,d[i][j]=min(d[i][j],d[i][k]+dp[k][j]),关键是在此之前要得到d[i][k]和d[k][j],因此是先枚举k。在枚举到k之前,k并不会作为某条最短路的中间点。所以只要保证每个结点是依次加入到图中的,那么每次用新加入的结点作为中间点更新所有的最短路,得到的就是此时图上的最短路。这道题的输入刚好是按加入顺序(每次询问t递增)。

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 const int maxn = 205, inf = 0x3f3f3f3f;
     5 
     6 int repair[maxn], dist[maxn][maxn];
     7 
     8 int main() {
     9     int n, m, q;
    10     scanf("%d%d", &n, &m);
    11     for (int i = 0; i < n; ++i) scanf("%d", &repair[i]);
    12     repair[n] = inf;
    13     memset(dist, inf, sizeof(dist));
    14     for (int i = 1; i <= m; ++i) {
    15         int u, v, w;
    16         scanf("%d%d%d", &u, &v, &w);
    17         dist[u][v] = dist[v][u] = w;
    18     }
    19     scanf("%d", &q);
    20     int x, y, t;
    21     scanf("%d%d%d", &x, &y, &t);
    22     --q;
    23     for (int k = 0; k <= n; ++k) {
    24         while (t < repair[k]) {
    25             if (repair[x] > t || repair[y] > t || dist[x][y] == inf)
    26                 printf("-1
    ");
    27             else printf("%d
    ", dist[x][y]);
    28             if (!q) return 0;
    29             scanf("%d%d%d", &x, &y, &t);
    30             --q;
    31         }
    32         for (int i = 0; i < n; ++i)
    33             for (int j = 0; j < n; ++j)
    34                 if (dist[i][j] > dist[i][k] + dist[k][j])
    35                     dist[i][j] = dist[i][k] + dist[k][j];
    36     }
    37     return 0;
    38 }
    AC代码
  • 相关阅读:
    Solaris+Oracle安装(详细图解)
    linux卸载和安装jdk
    UTF8, Unicode, GB2312格式串转换之C语言版
    linux安装ant
    在 Linux 平台下使用 JNI
    华为C/C++笔试题(1)
    c面试
    mongodb数据库
    YARN
    NPM(包管理器)
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9553508.html
Copyright © 2011-2022 走看看