Codeforces 189D AlgoRace floyd+DP

D. AlgoRace
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

PMP is getting a warrior. He is practicing a lot, but the results are not acceptable yet. This time instead of programming contests, he decided to compete in a car racing to increase the spirit of victory. He decides to choose a competition that also exhibits algorithmic features.

AlgoRace is a special league of car racing where different teams compete in a country of n cities. Cities are numbered 1 through n. Every two distinct cities in the country are connected with one bidirectional road. Each competing team should introduce one driver and a set of cars.

The competition is held in r rounds. In i-th round, drivers will start at city si and finish at city ti. Drivers are allowed to change their cars at most ki times. Changing cars can take place in any city in no time. One car can be used multiple times in one round, but total number of changes should not exceed ki. Drivers can freely choose their path to destination.

PMP has prepared m type of purpose-built cars. Beside for PMP’s driving skills, depending on properties of the car and the road, a car traverses each road in each direction in different times.

PMP Warriors wants to devise best strategies of choosing car and roads in each round to maximize the chance of winning the cup. For each round they want to find the minimum time required to finish it.

Input

The first line contains three space-separated integers n, m, r (2 ≤ n ≤ 60, 1 ≤ m ≤ 60, 1 ≤ r ≤ 105) — the number of cities, the number of different types of cars and the number of rounds in the competition, correspondingly.

Next m sets of n × n matrices of integers between 0 to 106 (inclusive) will follow — describing the time one car requires to traverse different roads. The k-th integer in j-th line of the i-th set is the time that i-th car requires to traverse the road from j-th city to k-th city. These matrices are not necessarily symmetric, but their diagonal is always zero.

Next r lines contain description of the rounds. The i-th of these lines contains space-separated integers si, ti, ki (1 ≤ si, ti ≤ n, si ≠ ti, 0 ≤ ki ≤ 1000) — the number of starting city, finishing city and the number of possible car changes in i-th round, correspondingly.

Output

For each round you should print the minimum required time to complete the round in a single line.

Examples
input
4 2 3
0 1 5 6
2 0 3 6
1 3 0 1
6 6 7 0
0 3 5 6
2 0 1 6
1 3 0 2
6 6 7 0
1 4 2
1 4 1
1 4 3
output
3
4
3
input
4 2 3
0 7 3 3
8 0 10 5
1 1 0 4
8 9 2 0
0 3 3 9
7 0 4 9
3 8 0 4
4 8 9 0
2 3 3
2 1 3
1 2 2
output
4
5
3
Note

In the first sample, in all rounds PMP goes from city #1 to city #2, then city #3 and finally city #4. But the sequences of types of the cars he uses are (1, 2, 1) in the first round and (1, 2, 2) in the second round. In the third round, although he can change his car three times, he uses the same strategy as the first round which only needs two car changes.




n个城市,两两间有道路,有k种车,每种车在一对城市( i, j )之间行车花费的时间由一个n*n的方阵给出。多次询问,求从 i 到 j 换乘最多k次所花费的最少时间。


dp[ i ] [ j ] [k]表示从 i 到 j 换乘k次的最小时间。用floyd先求出一种车在每两个城市间的最短时间,再floyd求出dp[i][j][0],最后用类似floyd的形式推出dp[i][j][1],dp[i][j][2],.....dp[i][j][n].


#include <cstdio>
#include <iostream>
#include <string.h>
#include <string> 
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=61,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;   
const ld pi=acos(-1.0L);
int dp[maxn][maxn][1005],a[maxn][maxn][maxn];

int main() {
	int n,m,q,i,j,k,l,x,y,z;
	scanf("%d%d%d",&n,&m,&q);
	for (l=1;l<=m;l++) {
		for (i=1;i<=n;i++) 
			for (j=1;j<=n;j++) 
				scanf("%d",&a[l][i][j]);
		for (i=1;i<=n;i++) 
			for (j=1;j<=n;j++) {
				if (i==j) continue;
				for (k=1;k<=n;k++) {
					if (i==k||j==k) continue;
					a[l][j][k]=min(a[l][j][k],a[l][j][i]+a[l][i][k]);
				}
			}
	}
	meminf(dp);
	for (l=1;l<=m;l++) 
		for (i=1;i<=n;i++) 
			for (j=1;j<=n;j++) 
				for (k=1;k<=n;k++) 
					dp[j][k][0]=min(dp[j][k][0],a[l][j][i]+a[l][i][k]);
	for (l=1;l<=n;l++) 
		for (i=1;i<=n;i++) 
			for (j=1;j<=n;j++) 
				for (k=1;k<=n;k++) 
				    dp[j][k][l]=min(dp[j][k][l],dp[j][i][l-1]+dp[i][k][0]);
	for (i=1;i<=q;i++) {
		scanf("%d%d%d",&x,&y,&z);
		if (z>n) z=n;
		printf("%d\n",dp[x][y][z]);
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]中提到了一种树形动态规划的方法来解决CodeForces - 982C问题。在这个问题中,subtree指的是子连通块,而不是子树。为了使cnt_white - cnt_black尽可能大,可以使用两次树形动态规划来求解。第一次是自底向上的过程,维护一个dp数组,表示以每个节点为根的子树中的最大连通块。第二次是自顶向下的过程,处理自底向上过程中无法包含的树链所代表的子树。在第二次遍历中,需要维护一个sum变量,用于存储树链所代表的子树的贡献。根据ans\[u\]的正负,决定是否能对相邻的子节点做出贡献。如果ans\[u\]为正,则减去dp\[v\]就是树链所代表的子树的权值。最终,ans\[u\]代表包含节点u在内的子连通块的最大权值。\[1\] 问题: CodeForces - 982C 树形DP是什么问题?如何解决? 回答: CodeForces - 982C是一个树形动态规划问题。在这个问题中,需要求解子连通块的最大权值和,使得cnt_white - cnt_black尽可能大。解决这个问题的方法是使用两次树形动态规划。第一次是自底向上的过程,维护一个dp数组,表示以每个节点为根的子树中的最大连通块。第二次是自顶向下的过程,处理自底向上过程中无法包含的树链所代表的子树。在第二次遍历中,需要维护一个sum变量,用于存储树链所代表的子树的贡献。根据ans\[u\]的正负,决定是否能对相邻的子节点做出贡献。最终,ans\[u\]代表包含节点u在内的子连通块的最大权值。\[1\] #### 引用[.reference_title] - *1* *2* [CodeForces - 1324F Maximum White Subtree(树形dp)](https://blog.csdn.net/qq_45458915/article/details/104831678)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值