CF187B AlgoRace

CF187B AlgoRace

洛谷传送门

题意翻译

有nn 个城市,两两之间有直接连边,还有mm 辆车。

已知这mm 辆车在(i,j)(i,j) 边上需要w_{i,j}w**i,j 的时间,但是你可以在到达一个城市之后选择换车,换车视为瞬间完成。对于每组询问(s,t,k)(s,t,k) ,求s\to tst 的最短时间,其中换车总次数不超过k-1k−1 ,即全程使用的车次不超过kk

询问有rr 组数据。其中

n,m\le 60 , w_{i,j}\le 10^6 , r\le 10^5n,m≤60,w**i,j≤106,r≤105 ;

1\le s,t\le n,k\le 10001≤s,tn,k≤1000 .

感谢@frankchenfu 提供的翻


题解:

一眼DP,看到这个数据范围觉得应该是多维状态。

所以直接按题意设:

\(dp[i][j][k]\)表示从i到j一共使用的车次不超过k的最短时间

那么可以看出,这个转移和中转点有关系。也就是枚举断点,类似\(Floyd\)的转移。但是还有这个换车的一维比较难搞。

稍加思索,觉得转移应该是这样的:

\[dp[i][j][k]=\min(dp[i][l][k-1]+dp[l][j][0])\quad(l\in (1,n)) \]

也就是,先换不超过k-1次车,最后不换车直接到达,因为断点处必然换一次车。

那么初值也就是不换车直达的时间。这个需要开始就做一遍松弛。

然后就看代码吧:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxq=1e5+5;
int n,m,r,maxx;
int dp[62][62][62];
//dp[i][j][k]表示i->j换k次车的最小时间
int a[62][62][62];
//a[k][i][j]表示i->j的原始时间
int q[maxq][3];
int main()
{
    scanf("%d%d%d",&n,&m,&r);
    for(int k=1;k<=m;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&a[k][i][j]);
    for(int i=1;i<=r;i++)
    {
        scanf("%d%d%d",&q[i][0],&q[i][1],&q[i][2]);
        maxx=max(maxx,q[i][2]);
    }
    maxx=min(maxx,n);
    for(int op=1;op<=m;op++)
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    a[op][i][j]=min(a[op][i][j],a[op][i][k]+a[op][k][j]);
    memset(dp,127,sizeof(dp));
    for(int op=1;op<=m;op++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                dp[i][j][0]=min(dp[i][j][0],a[op][i][j]);
    for(int k=1;k<=maxx+1;k++)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                dp[i][j][k]=dp[i][j][k-1];
        for(int l=1;l<=n;l++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    dp[i][j][k]=min(dp[i][j][k],dp[i][l][k-1]+dp[l][j][0]);
    }
    for(int i=1;i<=r;i++)
    {
        q[i][2]=min(q[i][2],maxx);
        printf("%d\n",dp[q[i][0]][q[i][1]][q[i][2]]);
    }
    return 0;
}
posted @ 2020-11-30 09:14  Seaway-Fu  阅读(136)  评论(0编辑  收藏  举报