Codeforces 765E. Tree Folding

Keywords: Programming

subject
Title Solution
Title: Give you a tree, which can be operated several times. Each operation can combine two chains of the same length according to a midpoint. Then ask you what the shortest chain length is after several merges.

Solution

Start with node 1, dfs.
For each node, a set record is used: the depth of the subtree rooted at that point.
(a) If a subnode of the node typed out GG, the node typed out GG directly.
b) If the number of elements of set is <=1, then the subtree rooted at that point is obviously possible.
Shrink into a chain drop! And the point is the end of the chain.
c) If the number of set elements is equal to 2, the subtree rooted at that point can also be contracted into a chain.
And this point is not the end of the chain. At this point, we will continue to discuss the classification.
i) There is no father at this point. We succeeded in finding a chain.
ii) If there is a father at this point, a strange thing will grow on the chain. Let's call the police, assign the point to root and call GG.
d) If the number of elements in the set is more than 2, hit GG directly!
If dfs is not available from the beginning, it must be the wrong way to open root. I started with root and tried dfs again.
If not, it's really GG.

Code

#include<bits/stdc++.h>
using namespace std;
const int N=200002;
struct node{
	int to,ne;
}e[N<<1];
int n,i,x,y,s,rt,h[N],tot;
inline char gc(){
	static char buf[100000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd(){
	int x=0,fl=1;char ch=gc();
	for (;ch<48||ch>57;ch=gc())if(ch=='-')fl=-1;
	for (;48<=ch&&ch<=57;ch=gc())x=(x<<3)+(x<<1)+(ch^48);
	return x*fl;
}
inline void wri(int a){if(a<0)a=-a,putchar('-');if(a>=10)wri(a/10);putchar(a%10|48);}
inline void wln(int a){wri(a);puts("");}
int dfs(int u,int fa){
	set<int>S;
	for(int i=h[u],v;i;i=e[i].ne)
		if ((v=e[i].to)!=fa){
			int t=dfs(v,u);
			if (t==-1) return -1;
			S.insert(t+1);
		}
	if (S.size()>2) return -1;
	if (!S.size()) return 0;
	if (S.size()==1) return *S.begin();
	if (S.size()==2 && !fa) return *S.rbegin()+*S.begin();
	rt=u;
	return -1;
}
void add(int x,int y){
	e[++tot]=(node){y,h[x]};
	h[x]=tot;
}
int main(){
	n=rd();
	for (i=1;i<n;i++) x=rd(),y=rd(),add(x,y),add(y,x);
	s=dfs(1,0);
	if (s==-1 && rt) s=dfs(rt,0);
	printf("%d",s/(s&-s));
}

Posted by cristal777 on Tue, 29 Jan 2019 17:24:15 -0800