[BZOJ1217][HNOI2003]消防局的设立(贪心)
这题也有树规的打法,但好复杂啊
贪心是这样的,对于深度最深的一个叶子节点,要覆盖它的话,肯定是覆盖它的爷爷是最优的
这样它的父亲跟兄弟都会被覆盖
所以每次找深度最深的,覆盖它的爷爷就行了
Code
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#define N 1010
using namespace std;
int n,head[N],tot,dep[N],fa[N],Ans;
struct info{int to,nex;}e[N*2];
struct cmp{bool operator() (int a,int b){return dep[a]<dep[b];}};
priority_queue<int,vector<int>,cmp> q;
bool vis[N];
inline void Link(int u,int v){
e[++tot].to=v;e[tot].nex=head[u];head[u]=tot;
}
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void dfs(int u,int fa){
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v==fa) continue;
dep[v]=dep[u]+1;
::fa[v]=u;
dfs(v,u);
}
}
void dddfs(int u,int dp){
if(dp>2) return;
vis[u]=1;
for(int i=head[u];i;i=e[i].nex) dddfs(e[i].to,dp+1);
}
int main(){
n=read();
for(int i=2;i<=n;++i){
int v=read();
Link(i,v),Link(v,i);
}
dfs(1,0);
for(int i=1;i<=n;++i) q.push(i);
while(!q.empty()){
while(!q.empty()&&vis[q.top()]) q.pop();
if(q.empty()) break;
dddfs(fa[fa[q.top()]]?fa[fa[q.top()]]:1,0);
++Ans;
}
printf("%d\n",Ans);
return 0;
}

浙公网安备 33010602011771号