zoukankan      html  css  js  c++  java
  • CF1029E

    一个看起来就不对的贪心居然是正解...

    但仔细思考一下,这种贪心倒的确找不到反例..

    贪心思想:每次找出离根节点最远的点,然后由根节点向这个点的父节点连边,一直连到所有点都能被覆盖即可,这样构造出的一定是一个可行的最优解

    正确性证明(个人YY):

    主要是要证明这种做法的最优性:

    首先,由于所有点都要求被覆盖,自然离根节点最远的点也不例外

    那么,如果想覆盖上离根节点最远的点,只会有两种覆盖方法:一种是将根节点与这个点本身相连,另一种是将根节点与这个点的父节点相连

    不难发现,将根节点与这个点的父节点相连,这样的方案一定不会差

    证明:假设这个父节点还有别的子节点,那么与父节点相连后这些子节点都能被覆盖,这样一定是更优的

    而即使这个父节点没有别的子节点,他还有自己的父节点,这样连边也能减少根节点与他的父节点的距离,也会达到更好的效果

    即使上面两点都没有起作用,至少这样还可以覆盖上最远的点,也并不会使代价增大,所以这样做是完全可行的。

    这样就完事了

    (ps:树上bfs真好用)

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    using namespace std;
    struct Edge
    {
    	int next;
    	int to;
    }edge[400005];
    bool used[200005];
    int head[200005];
    int f[200005];
    int n;
    int cnt=1;
    void init()
    {
    	memset(head,-1,sizeof(head));
    	cnt=1;
    }
    void add(int l,int r)
    {
    	edge[cnt].next=head[l];
    	edge[cnt].to=r;
    	head[l]=cnt++;
    }
    struct node
    {
    	int num;
    	int dep;
    }p[200005];
    void bfs(int rt)
    {
    	queue <int> M;
    	p[rt].dep=0;
    	p[rt].num=rt;
    	M.push(rt);
    	while(!M.empty())
    	{
    		int u=M.front();
    		M.pop();
    		for(int i=head[u];i!=-1;i=edge[i].next)
    		{
    			int to=edge[i].to;
    			if(p[to].dep)
    			{
    				continue;
    			}
    			p[to].dep=p[u].dep+1;
    			p[to].num=to;
    			f[to]=u;
    			M.push(to);
    			if(p[to].dep<=2)
    			{
    				used[to]=1;
    			}
    		}
    	}
    }
    bool cmp(node a,node b)
    {
    	return a.dep>b.dep;
    }
    int main()
    {	
    	scanf("%d",&n);
    	init();
    	for(int i=1;i<n;i++)
    	{
    		int x,y;
    		scanf("%d%d",&x,&y);
    		add(x,y);
    		add(y,x);
    	}
    	bfs(1);
    	sort(p+1,p+n+1,cmp);
    	int ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		if(used[p[i].num])
    		{
    			continue;
    		}
    		ans++;
    		int u=f[p[i].num];
    		used[u]=1;
    		for(int j=head[u];j!=-1;j=edge[j].next)
    		{
    			int to=edge[j].to;
    			used[to]=1;
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
  • 相关阅读:
    'yiiaseInvalidRouteException' with message 'Unable to resolve the request "site/error".'
    yii2:不使用composer安装yii2-jui的方法
    Oracle cmd乱码
    oracle 11g安装过程中问题:移动binoralbac11.dll 到binoralbac11.dll.dbl出错
    yii2打印数据属性(字段名)/数据
    在xampp集成环境下使用 php 连接oracle
    phalcon: 项目地址/P(.*), 项目地址/Pbaidu 与 路由
    PHP返回32位与16位的md5加密值
    PHP调用webservice接口
    java:日期格式化
  • 原文地址:https://www.cnblogs.com/zhangleo/p/10764170.html
Copyright © 2011-2022 走看看