CF E .Tree with Small Distances(树上的贪心)
题意:
这是一颗有n-1条边的无向树 , 在树上加最少的边使树的1节点到其他节点的距离最多为 2 ;
分析:很容易考虑的贪心的做法,但是该如何的贪心呢 ? 我一开始是打算贪心节点的儿子最多那一个 , 但这样是不行的,举个反例子例:1-2 ; 2-3 ; 3-4 ; 3-5 ; 3-6 ; 3-7 ; 4-8 ; 4-9 ; 5-10 ; 5-11 ; 6-12 ; 6-13 ; 7-14 ; 7-15 ; 可自己做出图,按这样的贪心出来的结果是5 ; 结果是4,所以这样的贪心是不行的 ; 我们在考虑其他的贪心做法;
我们可以来思考一下,能拿什么来贪心,节点度数,节点距顶点1的距离,节点的儿子数,节点的父节点,总共也就这么几个指标,可以进行排除法。
因此可以发现度数、儿子数、节点数都不可以,因为没有办法满足当前最优,但是距离是可以的,因为离节点1越远的点越难通过加边到达,因此应该按照距离进行贪心,然后就又出现了一个问题。
很多人进行到这步之后,就会理所当然的认为找到距离最远的点,然后让节点1和该点连一条边,然后很自然地就wa了...
仔细思考一下,找到这个点之后,应该和谁连边,是和该节点的儿子、父亲还是节点本身,儿子显然不成立,如果和父亲连边显然比本身更优,因此题目就可以解决了。
为什么呢? 我们是贪心出距离最长的节点优先考虑连边,故是从下肉上递推 ,而最长的节点一定是树的根节点,故连接该节点的父亲节点所得出来的贡献更大:
#include<bits/stdc++.h>
using namespace std;
int n ;
priority_queue<pair<int , int > > q;
vector<int>G[];
bool book[];
int per[],dis[];
void init( )
{
for(int i= ; i<=n ; i++)
book[i]=;
for(int i= ; i<=n ; i++)
G[i].clear();
while(q.size())
q.pop();
}
void dfs(int cur , int fa)
{
per[cur] = fa ;
for(int i= ; i<G[cur].size() ; i++)
{
int v = G[cur][i] ;
if(v==fa)
continue ;
dis[v] = dis[cur] + ;
if(dis[v]>)
q.push(make_pair(dis[v],v));
else
book[v]=;
dfs(v,cur);
}
} int main( )
{ scanf("%d",&n);
for(int i= ; i<=n- ; i++)
{
int u,v ;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(,-);
int ans=;
while(q.size())
{
int v = q.top().second;q.pop();
if(book[v]==)
continue;
int fa=per[v];
book[fa]=;
ans++;
printf("%d %d\n",v,fa);
for(int i= ; i<G[fa].size() ; i++)
{
int cur = G[fa][i];
book[cur]=;
}
}
printf("%d\n",ans);
return ;
}
CF E .Tree with Small Distances(树上的贪心)的更多相关文章
- CF 1029E Tree with Small Distances
昨晚随便玩玩搞个div3结果浪翻了…… 强烈谴责D题hack数据卡常 考虑到本题中所要求的最短距离不会大于2,所以我们可以把所有结点到$1$的距离通过对$3$取模分类,考虑到直接自顶向下贪心不满足局部 ...
- codeforces 1029E Tree with Small Distances【思维+贪心】 【非原创】
题目:戳这里 学习博客:戳这里 题意:给一个树加最少的边,使得1到所有点的距离小于等于2. 解题思路:分析样例3可以看出,如果一个点到1的距离大于2,那么建立1到该点的父亲节点的边将比直接与该点建边更 ...
- 树的最小支配集 E - Cell Phone Network POJ - 3659 E. Tree with Small Distances
E - Cell Phone Network POJ - 3659 题目大意: 给你一棵树,放置灯塔,每一个节点可以覆盖的范围是这个节点的所有子节点和他的父亲节点,问要使得所有的节点被覆盖的最少灯塔数 ...
- 【bzoj4813】[Cqoi2017]小Q的棋盘 树上dfs+贪心
题目描述 小Q正在设计一种棋类游戏.在小Q设计的游戏中,棋子可以放在棋盘上的格点中.某些格点之间有连线,棋子只能在有连线的格点之间移动.整个棋盘上共有V个格点,编号为0,1,2…,V-1,它们是连通的 ...
- Codeforces 1029 E. Tree with Small Distances(树上dp)
题目直通车:http://codeforces.com/problemset/problem/1029/E 思路大意:在树上做dp,依次更新ar数组,ar[i]表示以i为根节点的子树对答案的最小贡献值 ...
- Count on a tree(SPOJ COT + 树上第k大 + 主席树 + LCA)
题目链接:https://www.spoj.com/problems/COT/en/ 题目: 题意: 给你一棵有n个节点的树,求节点u到节点v这条链上的第k大. 思路: 我们首先用dfs进行建题目给的 ...
- (1009) HDU 6446 Tree and Permutation(规律+树上各个点的距离和)
题意: 给一棵N个点的树,对应于一个长为N的全排列,对于排列的每个相邻数字a和b,他们的贡献是对应树上顶点a和b的路径长,求所有排列的贡献和. 分析: 经过简单的分析可以得知,全部的贡献其实相当与(这 ...
- 【CF 675D Tree Construction】BST
题目链接:http://codeforces.com/problemset/problem/675/D 题意:给一个由n个互异整数组成的序列a[],模拟BST的插入过程,依次输出每插入一个元素a[i] ...
- CF 570D. Tree Requests [dsu on tree]
传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... ...
随机推荐
- HihoCoder1664 01间隔方阵([Offer收割]编程练习赛40)(DP)
给定一个NxM的01矩阵,小Hi希望从中找到一个01间隔的子方阵,并且方阵的边长越大越好. 例如对于 0100100 1000101 0101010 1010101 0101010 在右下角有一个4x ...
- bzoj 3779: 重组病毒 LCT+线段树+倍增
题目: 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病毒. 实验在一个封闭 ...
- windows拾遗
Files has invalid value "<<<<<<< .mine". Illegal characters in path.在 ...
- Spark Streaming之六:Transformations 普通的转换操作
与RDD类似,DStream也提供了自己的一系列操作方法,这些操作可以分成四类: Transformations 普通的转换操作 Window Operations 窗口转换操作 Join Opera ...
- Ruby中的%表示法
%{String} 用于创建一个使用双引号括起来的字符串,这个表示法与%Q{String}完全一样 result = %{hello} puts "result is: #{result ...
- linux命令-任务计划-cron
任务计划,有时间规律的执行某些事情. 查看任务计划:crontab -l 指定用户:crontab -l -u 用户名 该用户没有任务计划. 自定义任务计划 进入一个操作和vim类似的界面 用空格分 ...
- winform 客户端 HTTP协议与服务端通信以及解决中文乱码
本来从来没有仔细研究过Http协议,今天因为公司业务需求,调试了半天,终于现在会Winform用Http协议与服务端通信了,其中常用的有POST和Get方式: 仔细看了人人网和新浪等大部分都是采用GE ...
- CentOS7下yum方式安装mysql5.6
在Centos7中用MariaDB代替了mysql数据库.所以在新安装MySQL前必须做好对系统的清理工作. 一.清理CentOS7下的MariaDB. [root@localhost ~]#rpm ...
- ANDROID开发中资源文件和资源ID是如何映射的
http://tweetyf.org/2013/02/mapping_between_res_resid_android.html
- 应用程序无法正常启动提示错误0xc000007b 问题的原因和解决方法
应用程序无法正常启动提示错误0xc000007b 问题的原因和解决方法 前提条件: 你使用的是VS201x软件编写程序,你使用的电脑是X64位的,并且你在使用OpenCV库.你编写的程序可以正常编译, ...