hdu 6331 - 分块 + dp

题目链接:点击这里

解题思路:考虑从s走到u至少经过k条路的最少花费可以等价于:

ans[k] = max(f[B][s][i]+F[A][i][u]) i∈[1,n],(A*100 + B = k)

f[B][s][i]表示从s走到i刚好B步的最少花费,F[A][i][u]表示从i走到u至少A*100部的最少花费。

这样就可以把问题变成100的规模来算了。那么最后两个相加就是走至少A*100 + B步的最少花费了。

最后的问题就是最少A*100步的最少花费如何求,刚好100*A步的花费是比较好求的。那么我得再跑一个最短路,加上最短路的值就是至少100*A步的最少花费了。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int mx = 55;
const int N = 105;
const int mod = 1e9 + 7;
typedef long long ll;
int n,m,v[mx][mx]; 
int F[N][mx][mx],f[N][mx][mx];
int d[mx][mx];
void Get(int a[][mx],int b[][mx],int c[][mx])
{
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            c[i][j] = inf;
            for(int k=1;k<=n;k++){
                c[i][j] = min(c[i][j],a[i][k]+b[k][j]);
            }
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        memset(v,inf,sizeof(v));
        int a,b,c;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&a,&b,&c);
            v[a][b] = min(v[a][b],c);
        }
        for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) F[0][i][j] = f[0][i][j] = i==j? 0:inf;
        for(int i=1;i<N;i++) Get(f[i-1],v,f[i]);
        for(int i=1;i<N;i++) Get(F[i-1],f[100],F[i]);
        for(int i=1;i<=n;i++) 
        for(int j=1;j<=n;j++) d[i][j] = v[i][j]; 
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++) d[i][j] = min(d[i][j],d[i][k]+d[k][j]);
        for(int x=0;x<N;x++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    for(int k=1;k<=n;k++){
                        F[x][i][j] = min(F[x][i][j],F[x][i][k]+d[k][j]);
                    }
                }
            }
        }
        int q;
        scanf("%d",&q);
        while(q--){
            int S,T,K;
            scanf("%d%d%d",&S,&T,&K);
            int A = K/100,B = K%100;
            int ans = inf;
            for(int i=1;i<=n;i++) ans = min(ans,F[A][i][T]+f[B][S][i]);
            printf("%d\n",ans>=inf?-1:ans); 
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a1214034447/article/details/81415033