Codeforces #506 E. Tree with Small Distances

E. Tree with Small Distances

time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

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≤n≤2⋅10^5) — the number of vertices in the tree.

The following n−1 lines contain edges: edge is given as a pair of vertices ui,vi (1≤ui,vi≤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.

Examples

input

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

output

2

input

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

output

0

input

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

output

1

概述

    给定树,求最少添加多少边,使得节点1到所有节点的距离不超过2。

思路

    本题的突破口:

  • 设有任意两节点a,b,连接a-b总不比连接1-b好;
  • 分析如何处理终端节点c,连接1-c总不如连接1-d,其中d是c的父节点。

    按照上述规律,每次连接1与任意当前终端节点的父节点,贪心迭代即可。由于每次迭代终端节点未知,我按层(距离)从最远开始搜索终端节点。

    最坏时间复杂度O(nlogn)。

    虽说tutorial author认为存在O(n)dp解法,但我觉得这道题不论怎样搜索终端节点都需要O(nlogn)的复杂度,不存在O(n)的更优解法。

代码

#include<bits\stdc++.h> 
using namespace std; 
const int MAX=2e5+5;

bool x[MAX]{0};                //sign for search
int pre[MAX];                  //father node
vector<int> nxt[MAX],d[MAX];   //nxt:adjoining nodes of i;d:nodes of distance i
int dis;

int main(){
	int n;
	cin>>n;
    //save adjoining nodes
	for(int i=0;i<n-1;i++){
		int a,b;
		cin>>a>>b;
		nxt[a].push_back(b);
		nxt[b].push_back(a);
	}
    //search and save nodes of each distance
	x[1]=1;
	dis=0;
	d[0].push_back(1);
	while(!d[dis].empty()){
		for(auto a : d[dis])
			for(auto i : nxt[a]) if(!x[i]){
				x[i]=1;
				d[dis+1].push_back(i);
				pre[i]=a;
			}
		dis++;
	}dis--;
    //search terminal nodes by distance
	int cnt=0;
	while(dis>2){
		for(auto a : d[dis]) if(x[a]){
				cnt++;
				x[pre[a]]=0;
				for(auto j : nxt[pre[a]]) x[j]=0;
			}
		dis--;
	}
	cout<<cnt;
	return 0;
}

http://www.cnblogs.com/hizcard/  转载请注明出处 

猜你喜欢

转载自blog.csdn.net/hizcard/article/details/82117455