专栏文章

ABC397E题解

AT_abc397_e题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@mipwjo1s
此快照首次捕获于
2025/12/03 19:06
3 个月前
此快照最后确认于
2025/12/03 19:06
3 个月前
查看原文
考虑对于每一个结点,有三种可能:
  1. 和自己的其中一个子节点连为一条链。
  2. 和自己的两个子节点连为一条链,自己为链中间的一个结点。
  3. 自己所有子节点都可以独自构成一条长为 KK 的链,自己和父节点连为一条链。
不难发现,所有子节点构成的链的长度中最多只有两条不为 KK。当有一条时,可以将当前结点接到这个链上;当有两条时,可以将这两条一左一右和当前结点拼接,即当前结点为这条链中间的一个点,然后计算这个长度,若不为 KK 则输出 No
我们设计一个 dfs 函数,它的返回值为以这个点为端点的链的长度。及只有在第 11 和第 33 种情况时才会返回这个长度,当为第 22 种情况时,返回 00。当不满足情况,即要输出 No 时,返回 1-1
那么我们只需要在 dfs 过程中开一个数组记录一下每个 dfs 的返回值,然后再数一下数组中有多少个值不为 KK,再跟上一个判断就行了。
CPP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int MAXN = 2e5+5;

int n, k;
vector<int> e[MAXN];

int dfs(int u, int fa)
{
	vector<int> siz;
	for(int i = e[u].size()-1;i >= 0;i--)
	{
		int v = e[u][i];
		if(v == fa) continue;
		int sz = dfs(v, u);
		if(sz) siz.push_back(sz);
		if(sz == -1) return -1;
	}
	int cnt = 0;
	int re = 0;
	vector<int> sta;//存的是长度不为 K 的链的长度
	for(int i = siz.size()-1;i >= 0;i--)
	{
		int sz = siz[i];
		if(sz != k)
		{
			sta.push_back(sz);
		}
	}
	if(sta.size() > 2)
	{
		return -1;
	}
	if(sta.size() == 1)
	{
		return sta[0]+1;
	}
	if(sta.size() == 2)
	{
		if(sta[0] + sta[1] + 1 != k) return -1;
		else return 0;
	}
	return 1;
  //最后记得要return 1(我就是这个 1 打成 0 了赛后4min才调出来)
}

int main()
{
	scanf("%d%d", &n, &k);
	for(int i = 1;i < n * k;i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	int re = dfs(1, 0);
	printf(re == k || re == 0 ? "Yes" : "No");
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...