P2279 [HNOI2003] 消防局的设立
P2279 [HNOI2003] 消防局的设立
思路
贪心,dp 不敢恭维。
先说贪心策略:调最深、未覆盖节点的爷爷放置。
再看下面代码为什么不行?
#include<bits/stdc++.h>
using namespace std;
const int N=1033,inf=(int)1e4+10;
vector<int>g[N];
int ans;
int f[N][2],n;
int bj[N];
void dfs0(int u,int fa){
for(auto v:g[u]){
if(v==fa)continue;
f[v][0]=u;
dfs0(v,u);
}
}
void dfs1(int u,int fa){
for(auto v:g[u]){
if(v==fa)continue;
dfs1(v,u);
}
if(!bj[u]){
ans++;
if(f[u][1]){
bj[f[u][1]]=1;
for(auto v:g[f[u][1]]){
bj[v]=1;
for(auto x:g[v]) bj[x]=1;
}
}
else if(f[u][0]){
bj[f[u][0]]=1;
for(auto v:g[f[u][0]]){
bj[v]=1;
for(auto x:g[v]) bj[x]=1;
}
}
else {
bj[u]=1;
for(auto v:g[u]){
bj[v]=1;
for(auto x:g[v]) bj[x]=1;
}
}
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=2;i<=n;++i){
int a;cin>>a;
g[i].push_back(a);
g[a].push_back(i);
}
dfs0(1,0);
for(int i=1;i<=n;++i)f[i][1]=f[f[i][0]][0];
dfs1(1,0);
cout<<ans;
return 0;
}
/*
12
1 2 1 4 2 3 6 7 2 2 11
2
1
*/
因为遍历顺序不一定由深到浅。如:

Code
#include<bits/stdc++.h>
using namespace std;
const int N=1033,inf=(int)1e4+10;
vector<int>g[N];
int ans;
int f[N][2],n,dep[N];
int bj[N];
void dfs0(int u,int fa){
for(auto v:g[u]){
if(v==fa)continue;
f[v][0]=u;
dep[v]=dep[u]-1;
dfs0(v,u);
}
}
vector<int>v;
int cmp(int x,int y){
return dep[x]<dep[y];
}
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=2;i<=n;++i){
int a;cin>>a;
g[i].push_back(a);
g[a].push_back(i);
}
dfs0(1,0);
for(int i=1;i<=n;++i)f[i][1]=f[f[i][0]][0];
for(int i=1;i<=n;++i)v.push_back(i);
sort(v.begin(),v.end(),cmp);
for(auto u:v){
if(!bj[u]){
ans++;
if(f[u][1]){
bj[f[u][1]]=1;
for(auto v:g[f[u][1]]){
bj[v]=1;
for(auto x:g[v]) bj[x]=1;
}
}
else if(f[u][0]){
bj[f[u][0]]=1;
for(auto v:g[f[u][0]]){
bj[v]=1;
for(auto x:g[v]) bj[x]=1;
}
}
else {
bj[u]=1;
for(auto v:g[u]){
bj[v]=1;
for(auto x:g[v]) bj[x]=1;
}
}
}
}
cout<<ans;
return 0;
}
/*
12
1 2 1 4 2 3 6 7 2 2 11
2
1
*/

浙公网安备 33010602011771号