Codeforces Round #670 (Div. 2) C (the center of gravity of the tree)

Title:

Give you a tree, you can delete an edge, add an edge (you can delete and add the same one), make the center of gravity of this tree unique, output the deleted edge, and the added edge.

Pre-knowledge:

The center of gravity and nature of the tree
  • First of all, we need to know what the center of gravity of the tree is. The center of gravity of the tree is: a node in the tree, he satisfies, delete this node, there are several connected blocks, the largest of these connected blocks is the smallest.
  • Some basic properties of the center of gravity are:
    • All subtrees obtained after deleting the center of gravity, the number of nodes does not exceed 1/2 of the original tree, and a tree has at most two centers of gravity;
    • The sum of the distances from all nodes in the tree to the center of gravity is the smallest. If there are two centers of gravity, the sum of their distances is equal;
    • The two trees are merged through an edge, and the new center of gravity is on the path of the two centers of gravity of the original tree;
    • Delete or add a leaf node to the tree, and the center of gravity can only move one edge at most;
    • A tree has at most two centers of gravity, and they are adjacent.
The method of focus:
  • Turn the unrooted tree into a rooted tree, find each node as the root node, and record the size of the subtree as sz [i] sz[i]s z [ i ] , then the size of the largest subtree with each node as the root node ismax (sz [i] − 1, sz [fa] − sz [i]) max(sz[i]-1,sz[ fa]-sz[i])max(sz[i]1,s z [ f a ]s with [ i ] )

answer:

Find the center of gravity. If there are two, then the two must be on the same side (as can be seen from the nature of the center of gravity). I move the sub-branch of the center of gravity to another sub-branch.

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
vector<int>G[100005];
int f[100005],sz[100005],mx[100005];
void dfs(int u,int fa) {
    
    
	f[u] = fa;
	sz[u] = 1;
	for(auto v : G[u]) {
    
    
		if(v != fa) {
    
    
			dfs(v,u);
			sz[u] += sz[v];
			mx[u] = max(mx[u],sz[v]);
		}
	}
}
int main()
{
    
    
	int T;
	cin >> T;
	while(T--)
	{
    
    
		int n;
		cin >> n;
		
		for(int i=1;i<n;i++)
		{
    
    
			int u,v;
			scanf("%d%d",&u,&v);
			G[u].pb(v);
			G[v].pb(u);
		}
		dfs(1,0);
		int inf = 1e9,core;
		for(int i=1;i<=n;i++) {
    
    
			mx[i] = max(mx[i],sz[1]-sz[i]);
			
			if(mx[i] < inf) {
    
    
				inf = mx[i];
				core = i;
			}
		}
		
		int flag = 0;
		vector<int>ans;
		for(int i=1;i<=n;i++)
		{
    
    
			if(mx[i] == inf)ans.pb(i);
		}
		
		if(ans.size() == 1) {
    
    
			cout<<ans[0]<<' '<<G[ans[0]][0]<<'\n';
			cout<<G[ans[0]][0]<<' '<<ans[0]<<'\n';
		} else {
    
    
			int tmp;
			for(auto v : G[ans[0]]) {
    
    
				if(v != ans[1])
				{
    
    
					tmp = v;
					break;
				}
			}
			cout<<ans[0]<<' '<<tmp<<'\n';
			cout<<tmp<<' '<<ans[1]<<'\n';
		}
		
		
		for(int i=1;i<=n;i++)
		{
    
    
			sz[i] = 0;
			mx[i] = 0;
			G[i].clear();
			f[i] = 0;
		}
	}
 } 

Guess you like

Origin blog.csdn.net/weixin_44499508/article/details/108566477