您的位置:首页 > 编程语言 > Go语言

Codeforces Round #119 (Div. 1) B. AlgoRace

2012-11-25 14:04 369 查看

题意

意思就是说给了 m(1<=m<=60) 个车,以及每个车在每两座城市之间行走所花的时间,城市数量为 n(1<=n<=60),现在给了 r 个询问:从城市 s 到城市 t,允许中途更换 k 辆车(换车不需要时间)所花的最短时间是多少

做法分析

动态规划无疑了,主要是对 floyd 算法的动态规划意义要理解
先说说 floyd 算法求任意两点之间的最短路的动态规划意义吧:f[i][j][k] 其实表示的是:从城市 i 到城市 j,中途允许经过的城市是 1~k 的最短路径,我们可以看看 floyd 算法的三重循环:



而我们通常的写法是用的二维数组,即:



想想为什么?
这道题其实就是一个变形:定义状态:f[i][j][T][k] 表示 从城市 i 到城市 j 只允许经历 1~k 这几个城市,最多换 T 辆车的最短路,同样的,最后一位状态我们是可以省略的:精简的表示为:f[i][j][T] 状态可以这样转移: f[i][j][T] = min( f[i][j][T], f[i][k][T-1]+f[k][j][0] )

AC通道

Codeforces Round #119 (Div. 1) B. AlgoRace

参考代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

int f[65][65][65];
int g[65][65][65];

int main()
{
int n, m, r;
scanf("%d%d%d", &n, &m, &r);
memset(g, 0x7f, sizeof(g));
memset(f, 0x7f, sizeof(f));
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
for(int k=1; k<=n; k++)
scanf("%d", &g[i][j][k]);
for(int id=1; id<=m; id++)
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
g[id][i][j]=min(g[id][i][j], g[id][i][k]+g[id][k][j]);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
for(int k=1; k<=m; k++)
f[i][j][0]=min(f[i][j][0], g[k][i][j]);
for(int kk=1; kk<=n; kk++)
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
f[i][j][kk]=min(f[i][j][kk], f[i][k][kk-1]+f[k][j][0]);
while(r--)
{
int s, t, k;
scanf("%d%d%d", &s, &t, &k);
k=min(k, n);
printf("%d\n", f[s][t][k]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: