Tree diameter thinking [+] XR-3 core cities (Los Valley P5536)

[XR-3] core city

Title Description

X city owned n, n-1 pieces of a length of the road 1, each road connecting the two cities, and any two cities can reach each other by a plurality of roads, apparently, urban road, and forms a tree.

The king decided to Country X k Imperial cities as the core city of the country X, the following two conditions must satisfy the k cities:

  1. This k cities may, in the case of other cities without pairwise reach each other by road.
  2. The definition of a non-core seat k city and from this core of the city is, the minimum distance of the city and the seat k core of the city. Then all non-core cities, and from the largest urban core of the city, the minimum distance from the heart of the city. You need to find the minimum.

Input Format

The first line of two positive integers n, k.

Next, n-1 lines of two positive integers u, v, expressed between the u-v cities and cities of a length of a path.


Compare topic around, in fact, choose k points (k adjacent points), so that other points have not been selected to the maximum value of the minimum (distance to the nearest core city distance) from the k points;

I did not expect this problem is to use the tree diameter;

Release must be a point at the midpoint of the diameter of the tree, then the midpoint of the root dfs then again, the aim to find the maximum depth of all the sub-sub-tree nodes, and take the k + 1-th line (before k as a core cities);

Code:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100010;
const int M=2000100;
const LL mod=1e9+7;
int n,k,cnt,head[N],ans=0;
int st1,st2,max1,max2,len1[N],len2[N],len3[N],pre[N];
vector<int>ve;
bool cmp(int x,int y){return x>y;} 
struct Node{
	int to,nex;
}edge[M];
void add(int p,int q){
	edge[cnt].to=q;
	edge[cnt].nex=head[p];
	head[p]=cnt++;
}
void dfs1(int sn,int fa){
	if(len1[sn]>=max1){
		max1=len1[sn];
		st1=sn;
	}
	for(int i=head[sn];~i;i=edge[i].nex){
		int v=edge[i].to;
		if(v!=fa) len1[v]=len1[sn]+1,dfs1(v,sn);
	}
}
void dfs2(int sn,int fa){
	if(len2[sn]>=max2){
		max2=len2[sn];
		st2=sn;
	}
	for(int i=head[sn];~i;i=edge[i].nex){
		int v=edge[i].to;
		if(v!=fa){
			pre[v]=sn;
			len2[v]=len2[sn]+1;
			dfs2(v,sn);
		}
	}
}
void dfs3(int sn,int fa){
	len3[sn]=0;
	for(int i=head[sn];~i;i=edge[i].nex){
		int v=edge[i].to;
		if(v!=fa){
			dfs3(v,sn);
			len3[sn]=max(len3[sn],len3[v]+1);
		}
	}
}
int main(){
	memset(head,-1,sizeof(head));
	scanf("%d%d",&n,&k);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v),add(v,u);
	}	
	dfs1(1,-1);
	dfs2(st1,-1);
	for(int i=1;i<=(max2+1)/2;i++) st2=pre[st2];//找到直径中点 
	dfs3(st2,-1);
	for(int i=1;i<=n;i++) ve.push_back(len3[i]);
	sort(ve.begin(),ve.end(),cmp); 
	cout<<ve[k]+1<<endl;//第k+1个点明显最大 
	return 0;
}

Published 264 original articles · won praise 46 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_44291254/article/details/105187999