【HDU 5927】Auxiliary Set

1.题目链接。题目大意就是给了一棵树,这棵树上的节点有两种类别,一种是重要的点,一种是不重要的点。然后现在有一个集合,这个集合里面的节点满足两条性质中的任意一条即可:(1)这个节点是一个重要的节点.(2)这个节点不是一个重要的节点,但是这个节点是两个重要节点的LCA。然后是m组询问,每组询问首先给出一个数t,然后给出t个点,这t个点是不重要的节点,对于每组询问,输出一下这个集合的大小(也就是元素的数量)。

2分析一下可以知道,我们这个问题的主要矛盾就是在解决那些不重要的点中,有多少个是两个重要点的LCA。然后把重要的点加上去就是答案了。对于LCA我们知道,一个节点是他不同子树的LCA。然后我们只需要知道这个节点中儿子中重要节点的数量,如果这个数量大于等于2.那么这个节点就会被加入集合中,如果这个节点没有儿子,那么他对他的父亲贡献是0,所以父亲的儿子节点数减一。然后做法就比较明显了,我们一遍dfs,记录这样三个信息:当前节点的层数,节点儿子个数,节点的父亲。然后按照最底层从下向上更新即可。复杂度m*logm.

#include<bits/stdc++.h>
using namespace std;
#pragma warning(disable:4996)
const int N = 1e5 + 100;
vector<int>vec[N];
int dep[N];
int fa[N];
int cnt[N];
int vis[N];
int son[N];
struct node
{
	int x, d;
}no[N];
void dfs(int x, int y, int depth)
{
	fa[x] = y;
	dep[x] = depth;
	vis[x] = 1;
	for (int i = 0; i < vec[x].size(); i++)
	{
		if (vis[vec[x][i]])continue;
		cnt[x]++;
		dfs(vec[x][i], x, depth + 1);
	}
}
int cmp(node a, node b)
{
	return a.d > b.d;
}
int main()
{
	int n, m;
	int T;
	scanf("%d", &T);
	for (int ca = 1; ca <= T; ca++)
	{
		scanf("%d%d", &n, &m);
		memset(vis, 0, sizeof(vis));
		memset(cnt, 0, sizeof(cnt));
		for (int i = 0; i <= n; i++)vec[i].clear();
		for (int i = 1; i <n; i++)
		{
			int u, v;
			scanf("%d%d", &u, &v);
			vec[u].push_back(v);
			vec[v].push_back(u);
		}
		dfs(1, 0, 1);
		printf("Case #%d:\n", ca);
		while (m--)
		{
			int t;
			scanf("%d", &t);
			int ans = n - t;
			for (int j = 0; j < t; j++)
			{
				int x;
				scanf("%d", &x);
				no[j].x = x;
				no[j].d = dep[x];
				son[x] = cnt[x];
			}
			sort(no, no + t, cmp);
			for (int k = 0; k < t; k++)
			{
				if (son[no[k].x] >= 2)ans++;
				else if (son[no[k].x] == 0)son[fa[no[k].x]]--;
			}
			printf("%d\n", ans);
		}
	}
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值