102222F

给你一个图,图中每个点有对应的危险值,q个询问,每个询问给出起点,终点,限制值,需要你计算出从起点走到终点不走那些危险值超过限制值的最短路;(起点和终点的危险值不算)

我们康康floyed的思想。

显然我们在floyed的时候浪费掉了很多值,我们不妨记录一下用危险值第k小的点来更新ij的最短路,就好了。

dp就有用和不用两种情况。

我闲的蛋疼用vector离散化一直RE,换成数组就好了。

#include <bits/stdc++.h>
using namespace std;
int t,n,m;
int a[222],dis[222][222],id[222];
int dp[222][222][222];
bool cmp(int x,int y){
    return a[x]<a[y];
}
int main(){
    ios::sync_with_stdio(false);
    cin>>t;int cas=0;
    while (t--) {
        cin >> n >> m;cas++;
        for (int i = 1; i <= n; i++)cin >> a[i],id[i]=i;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cin >> dis[i][j];
                dp[i][j][0] = dis[i][j];
            }
        }
        sort(id+1,id+n+1,cmp);
        for (int k = 1; k <= n; k++) {//用前k小更新ij
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    dp[i][j][k] = min(dp[i][j][k - 1], dp[i][id[k]][k - 1] + dp[id[k]][j][k - 1]);
                }
            }
        }
        cout<<"Case #"<<cas<<':'<<endl;
        sort(a+1,a+1+n);
        int q, w, e;
        while (m--) {
            cin >> q>>w>>e;
            int id = upper_bound(a+1,a+1+n,e)-a-1;
            cout << dp[q][w][id] << endl;
        }
    }
}
View Code
原文地址:https://www.cnblogs.com/MXang/p/11202147.html