计蒜客 Yingchuan Online F题 (Floyd 变形)

题目链接:链接 https://nanti.jisuanke.com/t/41290

Firdaws and Fatinah are living in a country with nnn cities, numbered from 111 to nnn. Each city has a risk of kidnapping or robbery.

Firdaws's home locates in the city uuu, and Fatinah's home locates in the city vvv. Now you are asked to find the shortest path from the city uuu to the city vvv that does not pass through any other city with the risk of kidnapping or robbery higher than www, a threshold given by Firdaws.

Input

The input contains several test cases, and the first line is a positive integer TTT indicating the number of test cases which is up to 505050.

For each test case, the first line contains two integers n(1≤n≤200)n (1 le n le 200)n(1n200) which is the number of cities, and q(1≤q≤2×104)q (1 le q le 2 imes 10^4)q(1q2×104) which is the number of queries that will be given. The second line contains nnn integers r1,r2,⋯ ,rnr_1, r_2, cdots , r_nr1,r2,,rn indicating the risk of kidnapping or robbery in the city 111 to nnn respectively. Each of the following nnn lines contains nnn integers, the jjj-th one in the iii-th line of which, denoted by di,jd_{i,j}di,j, is the distance from the city iii to the city jjj.

Each of the following qqq lines gives an independent query with three integers u,vu,vu,v and www, which are described as above.

We guarantee that 1≤ri≤105,1≤di,j≤105(i≠j),di,i=01 le r_i le 10^5, 1 le d_{i,j} le 10^5 (i eq j), d_{i,i} = 01ri105,1di,j105(i=j),di,i=0 and di,j=dj,id_{i,j} = d_{j,i}di,j=dj,i. Besides, each query satisfies 1≤u,v≤n1 le u,v le n1u,vn and 1≤w≤1051 le w le 10^51w105.

Output

For each test case, output a line containing Case #x: at first, where xxx is the test case number starting from 111. Each of the following qqq lines contains an integer indicating the length of the shortest path of the corresponding query.

样例输入

1
3 6
1 2 3
0 1 3
1 0 1
3 1 0
1 1 1
1 2 1
1 3 1
1 1 2
1 2 2
1 3 2

样例输出

Case #1:
0
1
3
0
1
2


题意:两个人住在城市u,每天要去城市v,但是要经过一些城市和街道,而且每个城市都有危险值,要求找一条路的从城市u到城市v而且危险值不超过w的最短路径(q次查询 u, v,  w)。

题解:floyd的变形题。

我们考虑floyd算法的动态规划解释,F(k, i, j)代表从i顶点到j顶点可以经过前k个顶点的最短路。对于本题,我们用F [ k ] [ i ] [ j ] 代表从i城市到j城市可以经过危险值是前k小的城市的最短路径。

#include <bits/stdc++.h>

const int maxn=205;
int r[maxn], rnk[maxn], dp[maxn][maxn][maxn];

int cmp(int a, int b){
    return r[a]<r[b];
}

int main()
{
    int T, kase=0;
    for(std::cin>>T; T--; )
    {
        int n, q;
        scanf("%d%d", &n, &q);
        for(int i=1; i<=n; i++) scanf("%d", r+i);
        for(int i=1; i<=n; i++) rnk[i]=i;
        std::sort(rnk+1, rnk+1+n, cmp);
        memset(dp, 0x3f, sizeof(dp));
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                scanf("%d", &dp[0][i][j]);

        for(int k=1; k<=n; k++)  //危险值排名为前k个点和i,j 形成的最短路
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                    dp[k][i][j]=std::min(dp[k-1][i][j], dp[k-1][i][rnk[k]]+dp[k-1][rnk[k]][j]);

        printf("Case #%d:
", ++kase);
        while(q--)
        {
            int u, v, w, k;
            scanf("%d%d%d", &u, &v, &w);
            for(k=n; k; k--)
                if(r[rnk[k]]<=w) break;
            printf("%d
", dp[k][u][v]);
        }

    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Yokel062/p/11475418.html