K. Kingdom‘s Power,树形dp

Problem - K - Codeforces

time limit per test

2.0 s

memory limit per test

512 megabytes

input

standard input

output

standard output

Alex is a professional computer game player.

These days, Alex is playing a war strategy game. The kingdoms in the world form a rooted tree. Alex's kingdom 1 is the root of the tree. With his great diplomacy and leadership, his kingdom becomes the greatest empire in the world. Now, it's time to conquer the world!

Alex has almost infinite armies, and all of them are located at 1 initially. Every week, he can command one of his armies to move one step to an adjacent kingdom. If an army reaches a kingdom, that kingdom will be captured by Alex instantly.

Alex would like to capture all the kingdoms as soon as possible. Can you help him?

Input

The first line of the input gives the number of test cases, T (1≤T≤105). T test cases follow.

For each test case, the first line contains an integer n (1≤n≤106), where n is the number of kingdoms in the world.

The next line contains (n−1)integers f2,f3,⋯,fn (1≤fi<i), representing there is a road between fiand i.

The sum of n in all test cases doesn't exceed 5×106.

Output

For each test case, output one line containing "Case #x: y", where x is the test case number (starting from 1), and y is the minimum time to conquer the world.

Example

input

Copy

复制代码
2
3
1 1
6
1 2 3 4 4

output

Copy

复制代码
Case #1: 2
Case #2: 6

解析:

题意:

1号节点为根节点,根节点的军队数量是无线的,从根节点开始派兵,一次走一步,走遍所有的节点,需要多少步。

性质:若一棵子树都多个子树,这先走深度小的子树再走深度深的子树,是最优的;同时还要考虑是从一棵子树返回来走向另一棵子树还是从根节点派兵走

所以先dfs一次找出所有的节点的deep,再dfs找出最终答案;

具体见代码:(这道树形dp感觉跟dp没什么关系)

cpp 复制代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 5;
int n;
vector<pair<int, int>>G[N];
int deep[N];
LL ans;
int d = 0, flg = 0;

int dfs(int x,int fa) {
	deep[x] = deep[fa] + 1;
	if (G[x].size() == 0)return 1;
	for (int i = 0; i < G[x].size(); i++) {
		int j = G[x][i].second;
		int& v = G[x][i].first;
		v=dfs(j, x);
	}
	sort(G[x].begin(), G[x].end());
	return G[x].back().first + 1;
}

void dfs1(int x,int fa) {
	if (G[x].size() == 0) {
		if (flg == 0)ans += deep[x];
		else {
			ans += min(deep[x], d);
		}
		flg = 1;
		d = 0;
		return ;
	}
	for (int i = 0; i < G[x].size(); i++) {
		int j = G[x][i].second;
		d++;
		dfs1(j, x);
		d++;
	}
}
int main() {
	int T,cnt=0;
	scanf("%d", &T);
	while (T--) {
		cnt++;
		scanf("%d", &n);
		for (int i = 0; i <= n; i++)
			G[i].clear();
		for (int i = 2,a; i <= n; i++) {
			scanf("%d", &a);
			G[a].push_back({ 0,i });
		}
		deep[0] = -1;
		dfs(1,0);
		flg = 0, d = 0, ans = 0;
		dfs1(1,0);
		printf("Case #%d: %lld\n",cnt, ans);
	}
	return 0;
}
相关推荐
Coovally AI模型快速验证25 分钟前
MMYOLO:打破单一模式限制,多模态目标检测的革命性突破!
人工智能·算法·yolo·目标检测·机器学习·计算机视觉·目标跟踪
可为测控1 小时前
图像处理基础(4):高斯滤波器详解
人工智能·算法·计算机视觉
Milk夜雨1 小时前
头歌实训作业 算法设计与分析-贪心算法(第3关:活动安排问题)
算法·贪心算法
BoBoo文睡不醒2 小时前
动态规划(DP)(细致讲解+例题分析)
算法·动态规划
apz_end2 小时前
埃氏算法C++实现: 快速输出质数( 素数 )
开发语言·c++·算法·埃氏算法
仟濹3 小时前
【贪心算法】洛谷P1106 - 删数问题
c语言·c++·算法·贪心算法
CM莫问3 小时前
python实战(十五)——中文手写体数字图像CNN分类
人工智能·python·深度学习·算法·cnn·图像分类·手写体识别
sz66cm4 小时前
LeetCode刷题 -- 45.跳跃游戏 II
算法·leetcode
Amor风信子4 小时前
华为OD机试真题---战场索敌
java·开发语言·算法·华为od·华为
old_power5 小时前
【PCL】Segmentation 模块—— 基于图割算法的点云分割(Min-Cut Based Segmentation)
c++·算法·计算机视觉·3d