• [HNOI2003]消防局的设立


    题目:洛谷P2279、BZOJ1217。

    题目大意:一棵树上建立消防局,每个消防局能管到范围2以内的所有节点,问至少建立多少个消防局能管理到所有节点?

    解题思路:很神奇的贪心思路。

    首先,我们得保证深度大的节点能被覆盖,那么每次要选一个深度最大的节点进行考虑。dfs+排序即可。

    然后,为了让一个消防局发挥最大的威力,我们把它设在当前节点的爷爷上,这样既可以管理到当前节点,又可以管理其他更多节点。

    再然后就是处理已经被覆盖的节点,如果该节点已经被覆盖,则不用考虑。

    覆盖时注意考虑全面。别的就没有了。

    时间复杂度看你的排序,数据小$O(n^2)$也行,我用了优先队列(:o)。

    C++ Code:

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<ext/pb_ds/priority_queue.hpp>
    int n,ans,fa[1020];
    bool vis[1020];
    std::vector<int>e[1020];
    struct node{
    	int dep,num;
    	bool operator <(const node& rhs)const{return dep<rhs.dep;}
    }p[1020];
    __gnu_pbds::priority_queue<node>q;
    void dfs(int now){
    	for(int i=e[now].size()-1;i>=0;--i)
    	if(p[e[now][i]].dep==-1){
    		p[e[now][i]]=(node){p[now].dep+1,e[now][i]};
    		q.push(p[e[now][i]]);
    		dfs(e[now][i]);
    	}
    }
    int main(){
    	ans=0;
    	scanf("%d",&n);
    	memset(p,-1,sizeof p);
    	for(int i=2;i<=n;++i){
    		scanf("%d",&fa[i]);
    		e[fa[i]].push_back(i);
    	}
    	p[1]=(node){1,1};
    	q.push(p[1]);
    	dfs(1);
    	memset(vis,0,sizeof vis);
    	while(!q.empty()){
    		node now=q.top();
    		q.pop();
    		if(!vis[now.num]){
    			++ans;
    			//----------------------------------------------------------------
    			int rt=fa[fa[now.num]];
    			vis[rt]=vis[fa[rt]]=vis[fa[fa[rt]]]=true;
    			for(int i=e[rt].size()-1;i>=0;--i){
    				vis[e[rt][i]]=true;
    				for(int j=e[e[rt][i]].size()-1;j>=0;--j)
    				vis[e[e[rt][i]][j]]=true;
    			}
    			//-----father's father's son and father's father's son's sons-----
    			rt=fa[rt];
    			vis[fa[rt]]=vis[rt]=true;
    			for(int i=e[rt].size()-1;i>=0;--i)
    			vis[e[rt][i]]=true;
    			//--------grandfather's grandfather and grandfather's sons--------
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Linux 用户和组管理
    Bash 基础特性
    Linux 中常用的基础命令二
    Linux 中常用的基础命令一
    Linux 获取帮助
    Linux 基础入门二
    Linux 基础入门一
    计算机基础
    python 操作元组 列表===python中三大宝刀(字典已经再上一遍 说过)
    mysql 创建数据存储过程的申明
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7718227.html
Copyright © 2020-2023  润新知