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

    嘟嘟嘟

    看n那么小,刚开始我就想暴力dijkstra,结果O(Qnlogn)光荣TLE,竟得了80分……

    正解是floyd。

    考虑朴素的floyd,dis[i][j]表示 i 到 j 的最短路,然而最原始的是dis[k][i][j],以前k个点为中继点时 i 到 j 的最短路,于是有dis[k][i][j] = min(dis[i][j], dis[k - 1][i][k] + dis[k - 1][k][j])。然后为了空间把第一维优化掉了。

    那么这道题也同理,dis[k][i][j]表示k时刻 i 到 j 的最短路,然后我们边查询边更新,因为查询时间保证递增,所以对于每一次查询,枚举上一次查询到这一次查询的时间中所有的点作为中继点,然后O(n2)更新多源最短路。

    总复杂度O(n3 + Q)。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 2e2 + 5;
    21 inline ll read()
    22 {
    23   ll ans = 0;
    24   char ch = getchar(), last = ' ';
    25   while(!isdigit(ch)) last = ch, ch = getchar();
    26   while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    27   if(last == '-') ans = -ans;
    28   return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32   if(x < 0) x = -x, putchar('-');
    33   if(x >= 10) write(x / 10);
    34   putchar(x % 10 + '0');
    35 }
    36 
    37 int n, m, t[maxn];
    38 int dis[maxn][maxn];
    39 
    40 int main()
    41 {
    42   n = read(); m = read();
    43   Mem(dis, 0x3f);
    44   for(int i = 0; i < n; ++i) t[i] = read(), dis[i][i] = 0;
    45   for(int i = 1; i <= m; ++i)
    46     {
    47       int x = read(), y = read(), w = read();
    48       dis[x][y] = dis[y][x] = w;
    49     }
    50   int q = read();
    51   for(int h = 1, k = 0; h <= q; ++h)
    52     {
    53       int x = read(), y = read(), tim = read();
    54       while(t[k] <= tim && k < n)
    55     {
    56       for(int i = 0; i < n; ++i)
    57         for(int j = 0; j < n; ++j)
    58           dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
    59       k++;
    60     }
    61       if(dis[x][y] == INF || t[x] > tim || t[y] > tim) write(-1), enter;
    62       else write(dis[x][y]), enter;
    63     }
    64   return 0;
    65 }
    View Code
  • 相关阅读:
    SQL语句中----删除表数据drop、truncate和delete的用法
    Sql server 中的bulk insert语句使用
    [Err] 42000
    abstract class和interface的异同
    浅谈Overload和Override
    public,private,protected,以及default时的区别
    Integer与int的区别
    static关键字
    "=="和equals方法究竟有什么区别
    final关键字
  • 原文地址:https://www.cnblogs.com/mrclr/p/9878384.html
Copyright © 2011-2022 走看看