社区讨论

此处悬赏 5RMB 求调(必须是楼主的思路)

P2279[HNOI2003] 消防局的设立参与者 5已保存回复 16

讨论操作

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

当前回复
16 条
当前快照
1 份
快照标识符
@mlgxv8qu
此快照首次捕获于
2026/02/11 02:33
上周
此快照最后确认于
2026/02/11 02:39
上周
查看原帖
WA50pts,评测
当然证明楼主的思路不可能 AC(完全错误)也可以。
真的通过可以加楼主微信,id 为 lyh_17772458533。
CPP
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int n, root;
vector<int> graph[N];
int ans;
int rnd[N];//层数
int fa[N];
bool pull[N];//是否覆盖
void dfs(int u, int father)
{
	if (graph[u].size() == 1 && graph[u][0] == father)
	{
		rnd[u] = 1;
		return;
	}
	bool flag_deal = 0;//剪枝优化
	if (pull[u]) flag_deal = 1;
	for (auto v : graph[u])
	{
		if (v == father) continue;
		fa[v] = u;
		dfs(v, u);
		rnd[u] = max(rnd[v], rnd[u]);//取层数最大
	}
	rnd[u] += 1;
	//如果儿子都已经处理,此点处于下一个范围中,层数为1
	bool flag = 1;
	for (auto it : graph[u])
	{
		if (it == father) continue;
		flag = flag && pull[it];
	}
	if (flag)
	{
		rnd[u] = 1;
		return;
	}
	//如果层数为3,此时利益最大化,处理覆盖
	if (flag_deal == 0 &&rnd[u] == 3)
	{
		pull[u] = 1;
		for (auto it : graph[u])
		{
			pull[it] = 1;
			for (auto v : graph[it])
			{
				pull[v] = 1;
			}
		}
		ans++;
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin >> n;
	root = 1;
	for (int i = 2; i <= n; i++)
	{
		int j;
		cin >> j;
		graph[i].push_back(j);
		graph[j].push_back(i);
	}
//	for (int i = 1; i < n; i++)
//	{
//		int u, v;
//		cin >> u >> v;
//		graph[u].push_back(v);
//		graph[v].push_back(u);
//	}
	dfs(root, 0);
	//处理层数不足3的范围
	for (int i = 1; i <= n; i++)
	{
		if (pull[i] == 0)
		{
			ans++;
			if (fa[i] != 0) i = fa[i];
			pull[i] = 1;
			for (auto it : graph[i])
			{
				pull[it] = 1;
				for (auto j : graph[it])
				{
					pull[j] = 1;
				}
			}
		}
	}
	cout << ans << "\n";
	return 0;
}
/*
11
1 2 3 4 5 6 7 8 9 10
 */

回复

16 条回复,欢迎继续交流。

正在加载回复...