首页 > 代码库 > [HNOI2003]消防局的设立

[HNOI2003]消防局的设立

OJ题号:BZOJ1217、洛谷2279

思路:贪心。

先DFS记录各个结点的深度,然后从深度大的结点贪心,如果当前结点不安全,就在它爷爷地方开消防局,同时更新上下二代的安全信息。

 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<algorithm> 5 #include<functional> 6 const int N=1001; 7 int p[N]; 8 bool safe[N]={0}; 9 std::vector<int> c[N];10 struct Vertex {11     int id,depth;12     bool operator > (const Vertex &x) const {13         return this->depth>x.depth;14     }15 };16 Vertex v[N];17 void dfs(const int x,const int depth) {18     v[x].depth=depth;19     for(unsigned int i=0;i<c[x].size();i++) dfs(c[x][i],depth+1);20 }21 void update(const int x) {22     safe[p[x]]=safe[p[p[x]]]=true;23     for(unsigned int i=0;i<c[p[x]].size();i++) safe[c[p[x]][i]]=true;24     for(unsigned int i=0;i<c[x].size();i++) {25         safe[c[x][i]]=true;26         for(unsigned int j=0;j<c[c[x][i]].size();j++) {27             safe[c[c[x][i]][j]]=true;28         }29     }30 }31 int main() {32     int n;33     scanf("%d",&n);34     p[1]=1;35     v[1].id=1;36     for(int i=2;i<=n;i++) {37         v[i].id=i;38         scanf("%d",&p[i]);39         c[p[i]].push_back(i);40     }41     dfs(1,0);42     std::sort(&v[1],&v[n+1],std::greater<Vertex>());43     int ans=0;44     for(int i=1;i<=n;i++) {45         if(safe[v[i].id]) continue;46         update(p[p[v[i].id]]);47         ans++;48     }49     printf("%d\n",ans);50     return 0;51 }

 

[HNOI2003]消防局的设立