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

    题目大意:题目信息量太大,请自行浏览:https://www.luogu.org/problemnew/show/P1119

    多组询问,数据范围小,还是floyd。。。

    不过这一次还出现了有一些不能走的点,不能走也就罢了,过两天居然又能走了?!

    这都是些啥啊。。。

    好了,不扯别的,还是看题:

    注意题目中的条件限制!这是莫大的提示!

    第二行包含N个非负整数t0,t1,…,tN−1,表示了每个村庄重建完成的时间,数据保证了t0≤t1≤…≤tN−1

    接下来Q行,每行3个非负整数x,y,t,询问在第t天,从村庄x到村庄y的最短路径长度为多少,数据保证了t是不下降的。

    根据这个,我们取消了可持久化(炸空间)的可能!也就是说,我们可以边操作边输出!我们考虑一下枚举天数:

    首先,对于不能到达的情况,我们判断给出的两个点是否有到目前没有修好的就行

    那么对于最短距离呢?

    还是继续挖掘floyd的价值,我们枚举的k代表中间接口,如果我们不把不能走的点作为k,那么在目前这一天就对于其他能走的点没有影响

    你可能会说:不对啊,那他的最短路被更新了啊

    但是,能不能到达已经判断完毕,那么我们只要保证它不影响别人就行了

    时间复杂度:O(n^3)

    最后,附上本题代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 using namespace std;
     7 //Debug Yufenglin
     8 #define dej printf("Running
    ");
     9 #define dep1(x) cout<<#x<<"="<<x<<endl;
    10 #define dep2(x,y) cout<<#x<<"="<<x<<' '<<#y<<"="<<y<<endl;
    11 #define dep3(x,y,z) cout<<#x<<"="<<x<<' '<<#y<<"="<<y<<' '<<#z<<"="<<z<<endl;
    12 
    13 //Standfor Yufenglin
    14 #define LL long long
    15 #define LB long double
    16 #define reg register
    17 #define il inline
    18 #define maxn 200
    19 #define maxm 1005
    20 
    21 int n,m,q,k;
    22 int f[maxn+5][maxn+5],t[maxn+5];
    23 
    24 int main()
    25 {
    26     scanf("%d%d",&n,&m);
    27     memset(f,0x3f,sizeof(f));
    28     for(int i=0; i<n; i++)
    29     {
    30         scanf("%d",&t[i]);
    31         f[i][i]=0;
    32     }
    33     for(int i=1; i<=m; i++)
    34     {
    35         int x,y,z;
    36         scanf("%d%d%d",&x,&y,&z);
    37         f[x][y]=z,f[y][x]=z;
    38     }
    39     scanf("%d",&q);
    40     for(int i=1; i<=q; i++)
    41     {
    42         int x,y,z;
    43         scanf("%d%d%d",&x,&y,&z);
    44         while(t[k]<=z&&k<n)
    45         {
    46             for(int i=0; i<n; i++)
    47             {
    48                 for(int j=0; j<n; j++)
    49                 {
    50                     f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
    51                 }
    52             }
    53             k++;
    54         }
    55         if(x>=k||y>=k) printf("-1
    ");
    56         else printf("%d
    ",f[x][y]);
    57     }
    58     return 0;
    59 }
  • 相关阅读:
    Jenkins学习记录(三)
    Jenkins学习记录(二)
    并发编程
    黏包及解决方法
    socket通信,三次握手,四次挥手
    异常处理
    元类与魔法方法
    封装方法与多态
    组合与封装
    继承
  • 原文地址:https://www.cnblogs.com/yufenglin/p/10703087.html
Copyright © 2011-2022 走看看