• [LuoguP1119]灾后重建


    感觉线代能上九十,开心

    刷点水题

    题意就是不停地往图里面加点和对应的边

    然后询问点对的最短路长度

    $n$个点 $q$次询问 $nleq200,qleq50000$

    就是改改floyd就行了

    floyd本质上是$f[i][j][k] = min(f[i][j][k], f[i][t][k-1]+f[t][j][k-1])$

    每次加点的时候自己补上就行了

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 200 + 10, maxm = 40000 + 10, INF = 0x3f3f3f3f;
    int n, m;
    int t[maxn];
    int g[maxn][maxn], dis[maxn][maxn];
    int main(){
        ios::sync_with_stdio(false);
        cin >> n >> m;
        for(int i = 0; i < n; i++){
            cin >> t[i];
        }
        memset(dis, 0x3f, sizeof dis);
        memset(g, 0x3f, sizeof g);
        int u, v, w;
        for(int i = 0; i < m; i++){
            cin >> u >> v >> w;
            g[u][v] = g[v][u] = w;
        }
        for(int i = 0; i < n; i++){
            g[i][i] = dis[i][i] = 0;
        }
        int last = -1, now;
        for(int i = 0; i < n; i++){
            if(!t[i]){
                for(int j = 0; j < i; j++){
                    dis[i][j] = dis[j][i] = g[i][j];
                }
                last = i;
            }
            else break;
        }
        for(int k = 0; k <= last; k++){
            for(int i = 0; i <= last; i++){
                for(int j = 0; j <= last; j++){
                    dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
                }
            }
        }
        int q, x, y, day;
        cin >> q;
        while(q--){
            cin >> x >> y >> day;
            if(last == -1 || day > t[last]){
                now = last + 1;
                while(now < n && t[now] <= day){
                    for(int i = 0; i < now; i++){
                        dis[i][now] = dis[now][i] = g[i][now];
                    }
                    now++;
                }
                for(int k = last + 1; k < now; k++){
                    for(int i = 0; i < now; i++){
                        for(int j = 0; j < now; j++){
                            dis[k][i] = dis[i][k] = min(dis[k][i], dis[k][j] + dis[j][i]);
                        }
                    }
                    for(int i = 0; i < now; i++){
                        for(int j = 0; j < now; j++){
                            dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
                        }
                    }
                }
                last = now - 1;
            }
            if(dis[x][y] == INF) cout << -1 << endl;
            else cout << dis[x][y] << endl;
        }
        return 0;
    }
  • 相关阅读:
    WebUpLoder 能自动预览,能多实例,包括后台demo
    ajax请求总是进入Error里
    c#_1:后台post请求
    Echarts_1:水平柱体
    Hello World!
    python正则表达式
    python web.py出现ValueError: need more than 1 value to unpack
    web.py端口被占用的错误
    github commit时出现 Please tell me who you are.以及项目名称管理
    打飞机小游戏 python+pygame
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/12075133.html
Copyright © 2020-2023  润新知