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;
}
相关推荐
白狐_79824 分钟前
408数据结构第5章:树与二叉树②——遍历、线索树、森林与哈夫曼
数据结构·算法·深度优先
致Great4 小时前
科研人的 AI,不该只回答问题:我用字节TraeWork 跑了一遍真实研究任务
算法
纵有疾風起4 小时前
线性表的定义与基本操作 — 从逻辑结构到 ADT 接口
数据结构·算法·408·线性表·adt
测试_AI_一辰4 小时前
AI Agent 评测最隐蔽的坑-记忆
人工智能·算法·ai·自动化·ai编程
lucas_AI4 小时前
给YOLO检测器插 LoRA,'插对地方'比'插什么'更要命
人工智能·算法
LuminousCPP5 小时前
数据结构-时间与复杂度|时间/空间复杂度 + 两道力扣练习 + 二分查找复盘
c语言·数据结构·经验分享·算法·leetcode
Nil2085 小时前
leetcode 三数之和
数据结构·算法·leetcode
小小龙学IT5 小时前
C++ std::vector 底层实现深度解析:内存布局、扩容策略、移动语义与迭代器失效
开发语言·c++·算法
noipp5 小时前
推荐题目:洛谷 P16689 出征
java·开发语言·数据结构·c++·算法·洛谷·luogu
eBest数字化转型方案6 小时前
从工程视角拆解冰柜资产管理:拍照识别 pipeline、纯净度算法与 IoT 选型踩坑
人工智能·物联网·算法