pensamiento diámetro del árbol [+] XR-3 ciudades principales (el valle de Los P5536)

[-3 XR] ciudad núcleo

título Descripción

X Propiedad de la Ciudad N, N-1 piezas de una longitud de la carretera 1, cada carretera que conecta las dos ciudades, y cualquiera de las dos ciudades pueden alcanzar entre sí por una pluralidad de caminos, al parecer, de vías urbanas, y las formas de un árbol.

El rey decidió ciudades del país X k imperiales como la ciudad central del país X, las siguientes dos condiciones debe satisfacer las ciudades k:

  1. Este k ciudades pueden, en el caso de otras ciudades, sin llegar a pares entre sí por carretera.
  2. La definición de un asiento k ciudad no básicos y de este núcleo de la ciudad es, la distancia mínima de la ciudad y el k núcleo de asiento de la ciudad. A continuación, todas las ciudades no centrales, y desde el núcleo urbano más grande de la ciudad, la distancia mínima desde el centro de la ciudad. Es necesario encontrar el mínimo.

Formato de entrada

La primera línea de dos números enteros positivos n, k.

A continuación, n-1 líneas de dos números enteros positivos u, v, expresado entre las ciudades de u-V y ciudades de una longitud de un camino.


Comparar alrededor de tema, de hecho, elegir las letras k (k puntos adyacentes), de manera que otros puntos no han sido seleccionados para el valor máximo del mínimo (distancia a la distancia base de la ciudad más cercana) a partir de los puntos k;

No esperaba que este problema es utilizar el diámetro de los árboles;

Release debe ser un punto en el punto medio del diámetro del árbol, entonces el punto medio de los dfs de raíz, de nuevo, el objetivo de encontrar la profundidad máxima de todos los nodos de sub-sub-árbol, y tomar la k + 1-ésima línea (antes k como ciudades de la base);

código:

#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;
}

Publicados 264 artículos originales · alabanza won 46 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/qq_44291254/article/details/105187999
Recomendado
Clasificación