Union (diameter of the tree)

Meaning of the questions:

  A tree you, you can choose to disconnect one side so that one side and then connected to the smallest diameter of the tree, find the smallest diameter, can be off the edge, a set of points can be any off and the new connection point.

answer:

  Be integrated use requirements tree diameter.

  

  Consider a problem: There are two trees with diameters of $ l_1 $, $ l_2 $,

  Then after two trees merge the new tree is a minimum diameter of $ \ max (l_1, l_2, \ lceil \ frac {l_1} {2} \ rceil + \ lceil \ frac {l_2} {2} \ rceil + 1) $.

  Clearly the best choice when the merger is connected to the midpoint of the two trees, because the location does not make any other new tree diameter shorter.

  

  In this problem we first pretreated dfs two endpoints diameter, the diameter of a mark.

  Then the two endpoints, respectively, DP tree rooted at the longest chain in each sub-tree.

  DP enumeration broken edge, if the current broken edge on the diameter, then we can use a pre-determined value of the diameter of the new tree.

  If in diameter, the diameter of a subtree of the original diameter, the diameter of the other subtree available DP FIG.

  Recorded at a minimum and take the minimum number of trees can be.

  As for the third question, we just find a matching side, find the midpoint of the diameter of the cut after its two sub-trees can even edge.

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define R register
#define ll long long
inline ll read()
{
	ll aa=0;char cc=getchar();
	while(cc<'0'||cc>'9')cc=getchar();
	while(cc<='9'&&cc>='0')
		{aa=(aa<<3)+(aa<<1)+(cc^48);cc=getchar();}
	return aa;
}
inline int max(int x,int y){return (x>y)?x:y;}
const int N=300003,M=600003;
struct edge{int u,v;}ed[N];
int tot,first[N],ver[M],nxt[M];
inline void add(int x,int y)
{
	ver[++tot]=y;nxt[tot]=first[x];
	first[x]=tot;return;
}
int n,f[N],fg[N],g[M],ve[N],ansi;
void dp(int x,int fa,int ei)
{
	f[x]=fg[x]=g[ei]=0;
	for(R int i=first[x],v;i;i=nxt[i]){
		v=ver[i];if(v==fa)continue;
		dp(v,x,i);
		fg[x]=max(fg[x],f[x]+f[v]+1);
		g[ei]=max(g[ei],max(fg[v],f[x]+f[v]+1));
		f[x]=max(f[x],f[v]+1);
	}
	fg[x]=max(fg[x],g[ei]);
}
int dis[N],pre[N],vi[N],pi,pj;
void dfsi(int x,int fa)
{
	for(R int i=first[x],v;i;i=nxt[i]){
		v=ver[i];if(v==fa)continue;
		dis[v]=dis[x]+1;dfsi(v,x);
		pre[v]=x;
		if(dis[pj]<dis[v])pj=v;
	}
}
int dfsj(int x,int fa,int dep)
{
	if(dep==0&&vi[x]==1)return x;
	for(R int i=first[x],v,y;i;i=nxt[i]){
		v=ver[i];if(v==fa)continue;
		y=dfsj(v,x,dep-1);
		if(y)return y;
	}
	return 0;
}
void dfsk(int x,int fa,int lim)
{
	for(R int i=first[x],v;i;i=nxt[i]){
		v=ver[i];
		if(v==fa||v==lim)continue;
		dis[v]=dis[x]+1;
		dfsk(v,x,lim); pre[v]=x;
		if(dis[pj]<dis[v])pj=v;
	}
}
void getline()
{
	memset(vi,0,sizeof(vi));
	int now=pj;vi[now]=1;
	while(now!=pi)
		now=pre[now],vi[now]=1;
}
void solve(int x,int y)
{
	say [x] = 0; x = pj; DFSK (x, x, y); pi = pj; 
	say [pi] = 0; DFSK (pi, pi, y); 
	getline (); 
	int dfsj u = (pi, pi, say [pj] / 2); 
	
	say [y] = 0; pj = y; DFSK (y, y, x); pi = pj; 
	say [pi] = 0; DFSK (pi, pi, x); 
	getline (); 
	int v = dfsj (pi, pi, say [pj] / 2); 
	printf ( "% d% d% d% d \ n", x, y, u, v); 
} 
Int main () 
{ 
	//freopen("league.in","r",stdin); 
	//freopen("league.out","w",stdout); 
	n = read (); tot = 1; 
	for (int i = R 1, x, y; i <n; i ++) { 
		x = read (); y = read (); 
		add (x, y); add (y, x); 
		ed [i] = (edge) {x, y}; 
	} 
	
	Say [1] = 0; pj = 1; DFSI (1,1); pi = pj; 
	say [pi] = 0; DFSI (pi, pi) = ANSI say [pj]; 
	getline (); // Jing Zhao dao zhi
	
	dp(pj,pj,1);dp(pi,pi,1);
	
	for(R int i=1,x,y,u,v,z;i<n;++i){
		u=ed[i].u;v=ed[i].v;
		x=g[i<<1];y=g[i<<1|1];
		if(vi[u]&&vi[v])
			z=(x+1)/2+(y+1)/2+1;
		else z=dis[pj];
		z=max(z,max(x,y));
		if(z<ansi) ansi=z,ve[0]=0;
		if(z==ansi) ve[++ve[0]]=i;
	}
	printf("%d\n%d ",ansi,ve[0]);
	for(R int i=1;i<=ve[0];++i)printf("%d ",ve[i]);puts("");
	solve(ed[ve[1]].u,ed[ve[1]].v);return 0;
}
/*
4
1 2 
2 3 
3 4 
*/

Guess you like

Origin www.cnblogs.com/toot-wjh/p/11576881.html