• [題解](最短路)luogu_P1119災後重建


    一道好題,然而看題解做的......


    floyed的實質:只經過前k個點i到j的最短路,原狀態轉移方程為

    f [ k ] [ i ] [ j ]=min( f[ k-1 ] [ i ] [ j ],f[ k-1 ] [ i ] [ k ]+f [ k-1 ] [ k ] [ j ] )

    這樣壓掉一維就變成了我們熟悉的樣子

    而這題發現這裡的k剛好很符合題中時間這一要求,即時間不超過k時的最短路,而題中給的詢問t又是有序的(無序也可以排序)

    所以就每次就用這個點的時間去更新一遍所有點的最短路,即可達到題意的目的

    判斷一下時間是否超過了,或者能否到達即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=205;
    const int maxm=100010;
    int n,m,q;
    int t[maxn],d[maxn][maxn],a[maxn][maxn];
    void upd(int k)
    {
        for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        if(d[i][j]>d[i][k]+d[k][j])
        d[i][j]=d[j][i]=d[i][k]+d[k][j];
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)scanf("%d",&t[i]);
        memset(d,0x3f,sizeof(d));
        for(int i=0;i<n;i++)d[i][i]=0;
        for(int i=1,x,y,z;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            d[x][y]=d[y][x]=z;
        }
        scanf("%d",&q);
        int now=0;//用於記錄當前時間對應的編號,從第一個村莊開始 
        for(int i=1,x,y,z;i<=q;i++){
            scanf("%d%d%d",&x,&y,&z);
            while(t[now]<=z && now<n){
                upd(now);//依次更新點,使它可以被用來更新其他的點 
                now++;
            }//處理在它之前建立的村莊 
            if(t[x]>z || t[y]>z)printf("-1
    ");
            else{
                if(d[x][y]==0x3f3f3f3f)printf("-1
    ");
                else printf("%d
    ",d[x][y]);
            }
        }
    }
  • 相关阅读:
    POJ1700 Crossing River
    Glad to see you! CodeForces
    Summer sell-off CodeForces
    atcoderI
    Selling Souvenirs CodeForces
    Array Division CodeForces
    Tea Party CodeForces
    Atcoder F
    Atcoder E
    Average Sleep Time CodeForces
  • 原文地址:https://www.cnblogs.com/superminivan/p/10702406.html
Copyright © 2020-2023  润新知