消防局的设立
问题描述
由题意知,及给定一颗树,若节点内建立消防站,周围两个内均不需要建立消防站,问至少需要多少个消防站才能让整个树不发生不可控的火灾?
思路
·f[x][0]:至少让x向上2层之下都覆盖信号的答案。
·f[x][1]:至少让x向上1层之下都覆盖信号的答案。
·f[x][2]:至少让x自己及之下覆盖信号的答案。
·f[x][3]:至少让x向下1层之下都覆盖信号的答案。
·f[x][4]:至少让x向下2层之下都覆盖信号的答案。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=INT_MAX;
int n,f[1010][5];
vector<int> G[1010];
void dfs(int x) {
if(G[x].empty()) {
f[x][0]=1,f[x][1]=1,f[x][2]=1;
return;
}
for(int i:G[x]) dfs(i);
f[x][0]=1;
int mi=N,mn=N;
for(int i:G[x]){
f[x][0]+=f[i][4];
f[x][1]+=f[i][3];
f[x][2]+=f[i][2];
f[x][3]+=f[i][2];
f[x][4]+=f[i][3];
mi=min(mi,f[i][0]-f[i][3]);
mn=min(mn,f[i][1]-f[i][2]);
}
f[x][1]+=mi;
f[x][2]+=mn;
f[x][1]=min(f[x][1],f[x][0]);
f[x][2]=min(f[x][2],f[x][1]);
f[x][3]=min(f[x][3],f[x][2]);
f[x][4]=min(f[x][4],f[x][3]);
}
int main() {
cin>>n;
for(int i=2; i<=n; i++) {
int u;
cin>>u;
G[u].emplace_back(i);
}
dfs(1);
cout<<f[1][2];
}