[luogu1119] 灾后重建

传送门

Solution

虽然没做过多少Floyd的题……但是还是灵性了一波。

首先你会发现数据是有单调性的!那么我们就干脆一个一个点加进去跑Floyd就行了,那么怎么加点呢?

对于某个点key,我要把它加进去,我们可以假设它是起点,那么以i为中点,j为终点,跑一下平方的松弛操作;同上,分别假设key为终点,key为中点。

这样我们每加入一个点,它的循环次数跟跑一次完整的Floyd一样了,避免了重复计算。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 205
#define INF 100005

int Graph[MAXN][MAXN];
int vis[MAXN];
int over[MAXN];
int N,M,Q;

inline void add(int key){

    for(register int i=1;i<key;++i)
    for(register int j=1;j<key;++j){
        Graph[key][j] = std::min(Graph[key][j],Graph[key][i]+Graph[i][j]);
    }

    for(register int i=1;i<key;++i)
    for(register int j=1;j<key;++j){
        Graph[j][key] = std::min(Graph[j][key],Graph[j][i]+Graph[i][key]);
    }

    for(register int i=1;i<key;++i)
    for(register int j=1;j<key;++j){
        Graph[i][j] = std::min(Graph[i][j],Graph[i][key]+Graph[key][j]);
    }
}
int main(){

    std::memset(vis,0,sizeof(vis));

    scanf("%d%d",&N,&M);
    for(register int i=1;i<=N;++i){
        scanf("%d",&over[i]);
    }

    for(register int i=1;i<=N;++i)
    for(register int j=1;j<=N;++j){
        Graph[i][j] = INF;
    }

    int u,v,w;
    for(register int i=1;i<=M;++i){
        scanf("%d%d%d",&u,&v,&w);
        Graph[u+1][v+1] = w;
        Graph[v+1][u+1] = w;
    }

    int point = 0;
    scanf("%d",&Q);

    int t = 0;
    for(register int i=1;i<=Q;++i){
        
        scanf("%d%d%d",&u,&v,&t);
        u++;v++;

        for(;point<N&&over[point+1]<=t;){
            add(++point);
            vis[point] = 1;
        }

        if(vis[u]==0||vis[v]==0||Graph[u][v]==INF)puts("-1");
        else printf("%d\n",Graph[u][v]);
    }

    return 0;
}

转载于:https://www.cnblogs.com/Neworld2002/p/9689035.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值