消防局的设立
主要思路:贪心,从叶子节点开始(按深度排序即可做到),从它父亲的父亲,把距离不超过 \(2\) 的节点都打上标记,\(ans++\)。这样一定最优,因为必须覆盖那个没被覆盖的节点,而从祖父开始可以覆盖更多的点。注意把根节点的父亲设为根节点,否则从根节点开始跳就RE了
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,ans;
bool vis[N];
vector<int>g[N];
int p[N];
struct node2{
int depth,id;
}d[N];
bool cmp(node2 a,node2 b)
{
return a.depth>b.depth;
}
void dfs1(int now,int deep,int fa)
{
d[now].depth=deep;
p[now]=fa;
for(int i=0;i<g[now].size();i++)
{
if(g[now][i]==fa) continue;
dfs1(g[now][i],deep+1,now);
}
}
void era(int now,int dis,int fa)
{
if(dis>2)return;
vis[now]=true;
for(int i=0;i<g[now].size();i++)
{
if(g[now][i]!=fa)era(g[now][i],dis+1,now);
}
}
int main()
{
scanf("%d",&n);
p[1]=1;
d[1].id=1;
d[1].depth=1;
for(int i=2;i<=n;i++)
{
int x;
scanf("%d",&x);
d[i].id=i;
g[x].push_back(i);
g[i].push_back(x);
}
dfs1(1,1,1);
sort(d+1,d+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(vis[d[i].id])continue;
int grand=p[p[d[i].id]];
era(grand,0,grand);
ans++;
}
printf("%d\n",ans);
return 0;
}
路漫漫其修远兮,吾将上下而求索