Codeforces Round 862 (Div. 2) D

104 阅读2分钟

You are given a tree (a connected graph without cycles) with n vertices.

Consider a fixed integer k. Then, the graph Gk is an undirected graph with n vertices, where an edge between vertices u and v exists if and only if the distance between vertices u and v in the given tree is at least k.

For each k from 1 to n, print the number of connected components in the graph Gk.

Input

The first line contains the integer n (2≤n≤105) — the number of vertices in the graph.

Each of the next n−1 lines contains two integers u and v (1≤u,v≤n), denoting an edge between vertices u and v in the tree. It is guaranteed that these edges form a valid tree.

Output

Output n integers: the number of connected components in the graph Gk for each k from 11 to n.

Examples

input

Copy

6
1 2
1 3
2 4
2 5
3 6

output

Copy

1 1 2 4 6 6 

input

Copy

5
1 2
2 3
3 4
3 5

output

Copy

1 1 3 5 5 

Note

In the first example: If k=1, the graph has an edge between each pair of vertices, so it has one component. If k=4, the graph has only edges 4↔6 and 5↔6, so the graph has 4 components.

In the second example: when k=1 or k=2 the graph has one component. When k=3 the graph Gk splits into 3 components: one component has vertices 1, 4 and 5, and two more components contain one vertex each. When k=4 or k=5 each vertex is a separate component.

思路:树上问题手足无措的时候,可以拿一些比较特殊的树去思考:比如一条链。如果要在一条链上求上述问题,很显然k从大到小倒着求是好实现的。

代码:

void add(int a, int b)
{
	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

//找到距离 u 最远的顶点 v 
int dfs(int u, int fa = -1)
{
	int v = u;
	for(int i = h[u]; i != -1; i = ne[i])
	{
		int j = e[i];
		if(j == fa) continue;
		
		dis[j] = dis[u] + 1;
		int t = dfs(j, u);
		if(dis[v] < dis[t]) v = t;
	}		
	return v;
} 

void get_max_dis()
{
	dis[1] = 0;
	//距离 1 最远的 u 
	int u = dfs(1, -1);
	
	//距离 u 最远的 v
	//同时算出其他点到 u 的距离
	//u、v即为一条直径的两个端点 
	dis[u] = 0;
	int v = dfs(u, -1);	
	
    //更新
	for(int i = 1; i <= n; i++) maxDis[i] = max(maxDis[i], dis[i]);
	
	//计算其他点到 v 的距离 
	dis[v] = 0;
	dfs(v, -1);
    //更新
	for(int i = 1; i <= n; i++) maxDis[i] = max(maxDis[i], dis[i]);
}

void solve()
{
	cin >> n;
	for(int i = 1; i <= n; i++) h[i] = -1;
	for(int i = 1; i <= n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		add(a, b), add(b, a);	
	}	
    //预处理每个点到其他点的最大距离
	get_max_dis();
	int mxD = 0;
    //更新cnt数组
	for(int i = 1; i <= n; i++)
	{
		mxD = max(mxD, maxDis[i]);
		cnt[maxDis[i]]++;
	}
    //前缀和
	for(int i = 1; i <= mxD; i++) s[i] = s[i - 1] + cnt[i];
	for(int k = 1; k <= n; k++)
	{
		if(k > mxD) ans[k] = n;
		else ans[k] = n - (s[mxD] - s[k - 1]) + 1;
	}
	for(int k = 1; k <= n; k++) 
		cout << ans[k] << (k != n ? " " : endl);
}