社区讨论
贪心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 条回复,欢迎继续交流。
正在加载回复...