You are given an undirected tree consisting of \(n\) vertices. An undirected tree is a connected undirected graph with \(n−1\) edges.

Your task is to add the minimum number of edges in such a way that the length of the shortest path from the vertex 1 to any other vertex is at most 2 . Note that you are not allowed to add loops and multiple edges.

Input

The first line contains one integer \(n\) (\(2 \le n \le 2 \cdot 10^5 2≤n≤2⋅1e5\))-the number of vertices in the tree.

The following \(n - 1\) lines contain edges: edge \(i\) is given as a pair of vertices \(u_i, v_i\)(\(1 \le u_i, v_i \le n\)).

It is guaranteed that the given edges form a tree. It is guaranteed that there are no loops and multiple edges in the given edges.

Output

Print a single integer — the minimum number of edges you have to add in order to make the shortest distance from the vertex 1 to any other vertex at most 2 . Note that you are not allowed to add loops and multiple edges.

Sample Input1

7
1 2
2 3
2 4
4 5
4 6
5 7

Sample Output1

2

Sample Input2

71
1 2
1 3
2 4
2 5
3 6
1 7

Sample Output2

0

Sample Input3

7
1 2
2 3
3 4
3 5
3 6
3 7

Sample Output3

1

题意:

给你一棵树,让你从1往其他节点连边,使得1到任意节点的距离都小于等于2

题解:

我们设

\(dp[i][0]\)为不选\(i\)向根节点建边但以\(i\)为根的子树(包括\(i\))都被覆盖的最小费用

\(dp[i][1]\)为选\(i\)向根节点建边且以\(i\)为根的子树都被覆盖的最小费用

\(dp[i][2]\)为不选\(i\)向根节点建边但以\(i\)为根的子树(包括\(i\))都被覆盖的最小费用

然后我们可以愉悦的列出DP方程

\(dp[i][1]=1+\sum_{j}^{j\in son_i}min(dp[j][0],dp[j][1],dp[j][2])\)

如果选这个点,它的儿子的状态就无关了,取最小值就可以了。

\(dp[i][2]=\sum_j^{j\in son_i}dp[j][0]\)

如果这个点不选且要使这个点不被覆盖,就只能取它的儿子的0状态更新。

这两条方程还是比较好推的。主要是0状态比较难转移。

我们可以分类,若他的儿子中有一个点\(j\)满足\(dp[j][1]<dp[j][0]\),就有

\(dp[i][0]=\sum_{j}^{j\in son_i}min(dp[j][0],dp[j][1])\)

注意这里不能用儿子的2状态转移,这会导致那个点不被覆盖

但如果没有儿子满足,我们可以在他的儿子中找一个点\(k\),使\(dp[k][1]-dp[k][0]\)最小,然后使

\(dp[i][0]=\sum_{j}^{j\in son_i}dp[j][0]\qquad +dp[k][1]-dp[k][0]\)

就行了 。

#include<bits/stdc++.h>
using namespace std;
int n;
int tot,bian[400010],nxt[400010],head[200010];
int v[200010];
inline int read(){
register char c;register int ret=0;
for(c=getchar();c<'0'||c>'9';c=getchar());
for(;c>='0'&&c<='9';ret=(ret<<1)+(ret<<3)+c-'0',c=getchar());
return ret;
}
inline void add(int x,int y){
++tot;bian[tot]=y;nxt[tot]=head[x];head[x]=tot;
}
int dp[200010][3];
void dfs1(int x,int f,int d){
for(int i=head[x];i;i=nxt[i]){
if(bian[i]==f)continue;
dfs1(bian[i],x,d+1);
}
for(int i=head[x];i;i=nxt[i]){
if(bian[i]==f)continue;
dp[x][1]+=min(min(dp[bian[i]][0],dp[bian[i]][2]),dp[bian[i]][1]);
if(dp[x][2]<1e9)dp[x][2]+=dp[bian[i]][0];
}
int mn=1e9,b=0;
for(int i=head[x];i;i=nxt[i]){
if(bian[i]==f)continue;
if(dp[bian[i]][1]<dp[bian[i]][0])dp[x][0]+=dp[bian[i]][1],b=1;
else dp[x][0]+=dp[bian[i]][0];
mn=min(mn,dp[bian[i]][1]-dp[bian[i]][0]);
}
if(!b)dp[x][0]+=mn;
if(d>1)dp[x][1]++;
}
int main()
{
// freopen("traffic.in","r",stdin);
// freopen("traffic.out","w",stdout);
n=read();
for(int i=1;i<n;++i){
int x=read(),y=read();
add(x,y);
add(y,x);
}
dfs1(1,0,0);
cout<<min(dp[1][0],dp[1][1]);
}

Tree with Small Distances(cf1029E)(树形动规)的更多相关文章

  1. XJOI1571爱心蜗牛【树形动规】

    爱心蜗牛 猫猫把嘴伸进池子里,正准备"吸"鱼吃,却听到门铃响了.猫猫擦了擦脸上的水,打开门一看,那人正是她的好朋友--川川.川川手里拿着一辆玩具汽车,对猫猫说:"这是我的 ...

  2. 【树形动规】HDU 5834 Magic boy Bi Luo with his excited tree

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5834 题目大意: 一棵N个点的有根树,每个节点有价值ci,每条树边有费用di,节点的值只能取一次,边 ...

  3. 洛谷 P2986 [USACO10MAR]伟大的奶牛聚集(树形动规)

    题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...

  4. P2015 二叉苹果树 (树形动规)

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...

  5. [LUOGU1122] 最大子树和 - 树形动规

    题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明 ...

  6. 树形动规--没有上司的舞会--C++

    题目来源:code[VS] 题目描述 Description Ural大学有N个职员,编号为1~N.他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.每个职员有一个 ...

  7. [SDOI2011]消耗战(虚树+树形动规)

    虚树dp 虚树的主要思想: 不遍历没用的的节点以及没用的子树,从而使复杂度降低到\(\sum\limits k\)(k为询问的节点的总数). 所以怎么办: 只把询问节点和其LCA放入询问的数组中. 1 ...

  8. 洛谷 P2899 [USACO08JAN]手机网络Cell Phone Network(树形动规)

    题目描述 Farmer John has decided to give each of his cows a cell phone in hopes to encourage their socia ...

  9. P2014 选课 (树形动规)

    题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...

随机推荐

  1. 【WebService】WebService之CXF和Spring整合(六)

    前面介绍了WebService与CXF的使用,项目中我们经常用到Spring,这里介绍CXF与Spring整合 步骤 1.创建一个Maven Web项目,可以参照:[Maven]Eclipse 使用M ...

  2. 【Web】Nginx配置规则

    Nginx配置基本说明 以下是nginx的基本配置文件如下(编辑命令:vi /usr/local/nginx/conf/nginx.conf): #user nobody; #nginx进程数,建议设 ...

  3. [ASP.NET]使用Layer简介

    layer是一款近年来备受青睐的web弹层组件,她具备全方位的解决方案,致力于服务各水平段的开发人员,您的页面会轻松地拥有丰富友好的操作体验. 在与同类组件的比较中,layer总是能轻易获胜.她尽可能 ...

  4. NOIP水题测试(2017082401)

    哈,水题测试又来了! 上次的水题简单吧! 答案是以单题形式发布的(旅行家的预算随后发布). 下面来看今天的题,还是水题. 时间限制:5小时 题目一:看上去就很水 题目二:比上面一题还水 题目三:数的划 ...

  5. json(原生态)

    什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JSON 独立于语言 * JSO ...

  6. css过渡动画

    具体代码:1.水平翻转-moz-transform:scale(-1,1);-webkit-transform:scale(-1,1);-o-transform:scale(-1,1);transfo ...

  7. 2018.10.31 vijos1052贾老二算算术(高斯消元)

    传送门 高斯消元模板题. 写的时候反了sbsbsb错误消元的时候除数和被除数反了. 所以把板子贴上来压压惊. 代码: #include<bits/stdc++.h> using names ...

  8. ThinkPHP redirect 传参

    重定向带参 $this->redirect('pay/under_line_success',array('order_id'=>$stuInfo),5,'页面跳转中….'); 第一个参数 ...

  9. boost--BOOST_AUTO、typeof、result_of

    1.BOOST_AUTO BOOST_AUTO的功能类似于auto和any,可以用来定义任意类型数据,且可以在编译时自动推导出表达式的类型.BOOST_AUTO属于boost中的typeof库,使用需 ...

  10. 第08章:MongoDB-CRUD操作--文档--删除

    ①语法 remove()  [2.6以后方法过时] deleteOne() [2.6以后官方推荐] deleteMany() [2.6以后官方推荐] db.collection.remove( < ...