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

题意

    意思就是说给了 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 
#include 
#include 
#include 

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;
}


你可能感兴趣的:(ACM_图论,ACM_动态规划)