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

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

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

正确性证明(个人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\n",ans);
return 0;
}

CF1029E的更多相关文章

  1. Tree with Small Distances(cf1029E)(树形动规)

    You are given an undirected tree consisting of \(n\) vertices. An undirected tree is a connected und ...

  2. 贪心【CF1029E】Tree with Small Distances

    Description 给定一棵树.要求往树中加入一些边使得从1到其他节点的距离至多是2 . 输出加入边的最小数量.(边全部都是无向的) Input 第一行一个整数n,表示树中的节点个数. 接下来n− ...

  3. CF1029E Tree with Small Distances

    题目描述 给定一棵树.要求往树中加入一些边使得从1到其他节点的距离至多是2 . 输出加入边的最小数量.(边全部都是无向的) 题解:好多人都说是贪心,但是我写的是树形dp. (这道题实在太像小胖守皇宫了 ...

  4. CF1029E Tree with Small Distances (贪心)

    题目大意:给你一棵边权为1的树,让你加入一些边,使得根节点(1号节点)到其他节点的最短距离不大于2 并没有想到贪心...... 正解的贪心思路是这样的 用一个堆维护当前距离最远的点,然后把根节点和它的 ...

  5. 树形dp——cf1029E

    题解给出的是带log的,,我自己写了个on的.. #include<bits/stdc++.h> #include<vector> using namespace std; # ...

随机推荐

  1. vue购物车实战项02

    1.数据循环.绑定 v- 绑定的属性 都是变量 ( 小程序这块需要花括号 不同点) 2.列表点击 当绑定变量为一个对象的时候{} 属性根据里面的属性值 bool 值  是否返回 当前的属性 转化成cl ...

  2. 多次使用图片物理路径提示占用进程,用流读取设置FileShare权限解决

    //用流读取图片 清空之后再次关联地址 //设置FileShare.ReadWrite权限之后 不会提示占用进程异常 item是物理路径DiscussionImageList = new Interv ...

  3. Latex 编辑数学公式——快速上手

    参考链接: https://blog.csdn.net/fansongy/article/details/45368915 特殊符号: https://blog.csdn.net/caiandyong ...

  4. MySQL入门简介(转载)

    转载链接:https://www.cnblogs.com/webnote/p/5753996.html MySQL的相关概念介绍 MySQL 为关系型数据库(Relational Database M ...

  5. Windows Server 2008 R2忘记密码导致无法修改密码

    其实有个记住密码的工具还是简单的,登陆系统后,CMD输入命令: net user administrator NewPassword 新密码即时生效

  6. 很清晰的解读i2c协议【转】

    转自:https://blog.csdn.net/weixin_41718085/article/details/79376823 转载:http://dpinglee.blog.163.com/bl ...

  7. 华为QUIDWAY系列路由器的单臂路由配置案例

    作者:邓聪聪 单臂路由 单臂路由(router-on-a-stick)是指在路由器的一个接口上通过配置子接口(或“逻辑接口”,并不存在真正物理接口)的方式,实现原来相互隔离的不同VLAN(虚拟局域网) ...

  8. 设计模式C++学习笔记之六(Facade门面模式)

      Facade门面模式,也是比较常用的一种模式,基本上所有软件系统中都会用到. GOF 在<设计模式>一书中给出如下定义:为子系统中的一组接口提供一个一致的界面, Facade 模式定义 ...

  9. 浏览器开启桌面通知Web Notification

    本文主要描述如何开启各个浏览器的桌面通知功能 一.谷歌浏览器(chrome) 点击地址栏前面的图标

  10. QTableWidget

    1.QTableWidget继承自QTableView. QSqlTableModel能与QTableView绑定,但不能于QTableWidget绑定.​ QTableWidget是QTableVi ...