社区讨论

贪心80…………找不到贪心策略哪里错了…………求反例QAQ

P1041[NOIP 2003 提高组] 传染病控制(疑似错题)参与者 2已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mi7dfonn
此快照首次捕获于
2025/11/20 19:52
4 个月前
此快照最后确认于
2025/11/20 19:52
4 个月前
查看原帖
CPP
#include<cstdio>
using namespace std;
int depth[410],s[410],d[410][410],p[410],n,pp,cnt,head[410],f[410],v[410],md;
struct data{int to,next;}e[1010];
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int dfs(int u)
{
	depth[u]=depth[f[u]]+1;//深度 
	if (depth[u]>md) md=depth[u];//最大深度 
	d[depth[u]][++d[depth[u]][0]]=u;
	for (int i=head[u];i;i=e[i].next)
	{
		if (e[i].to==f[u]) continue;
		f[e[i].to]=u;
		dfs(e[i].to);
		p[u]+=p[e[i].to]; 
		s[u]++;//该节点的儿子数 
	}
	return ++p[u];//返回以该节点为根的子树节点总个数 
}
int main()
{
	scanf("%d%d",&n,&pp);
	for (int i=1,u,vv;i<n;i++)
	{
		scanf("%d%d",&u,&vv);
		add(u,vv);
		add(vv,u);
	}
	dfs(1);//建树,求出最大深度md,每个节点的父节点和d数组
		   //d[i][j]表示第i层第j个节点,d[i][0]表示第i层的节点个数 
	cnt=0;
	for (int i=2;i<=md;i++)
	{
		int max=0;
		for (int j=1;j<=d[i][0];j++)
		{
			if (v[f[d[i][j]]]==1)//如果父节点被预防,那么自己也应该被预防 
			{
				cnt++;//未感染人数+1 
				v[d[i][j]]=1;//标记被预防 
			}
			else if (s[d[i][j]]>s[max]||(s[d[i][j]]==s[max]&&p[d[i][j]]>p[max])) 
				max=d[i][j];//取儿子最多的节点
		}
		if (max)//如果存在没有被感染的节点,那么取儿子最多的节点预防掉 
		{
			cnt++;//未感染人数+1 
			v[max]=1;//标记被预防 
		}
	}
	printf("%d",n-cnt);//总人数-未感染人数 
}
自己想的数据都能跑(包括一条子节点为链然而不能删的情况)

回复

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

正在加载回复...