PAT.A1021 Raíz más profunda

Volver a contenidosInserte la descripción de la imagen aquí

Titulo

Dar n nodos y n-1 aristas. ¿Preguntar si pueden formar un árbol de n nodos? Si puede, el nodo de salida se usa como la raíz del árbol, de modo que la altura del árbol se maximiza y todos los nodos satisfechos se generan. Si no, se emite el número de bloques conectados.

Muestra (se puede copiar)

5
1 2
1 3
1 4
2 5
//output
3
4
5
5
1 3
1 4
2 5
3 4
//output
Error: 2 components

Puntos a tener en cuenta

  1. Hay dos problemas a resolver en este problema: ① Determinar si se puede formar un árbol ② Encontrar los nodos que pueden satisfacer las condiciones cuando se puede formar el árbol
  2. Para el problema ①, puede usar el método check-set o DFS para encontrar el número de bloques conectados Obviamente, cuando block = 1, se puede formar un árbol. Esta pregunta usa el método DFS.
  3. Hay dos soluciones al problema ②: la primera: encontrar el conjunto A del nodo más alejado de cualquier nodo, y luego seleccionar cualquier nodo en A para encontrar el conjunto B del nodo más alejado. Todos los nodos que cumplan las condiciones se omitirán aquí. Si usa este método para usar una colección, puede usar el conjunto de bibliotecas STL, que contiene la función set_union () que combina. Segundo: Encuentre la altura máxima del árbol cuando cada nodo se usa como nodo raíz, y finalmente compare la altura máxima para obtener los nodos que cumplan las condiciones. Esta pregunta usa el último.
#include<bits/stdc++.h>
using namespace std;

const int N=100010;
vector<int> G[N];
bool flag[N]={false};//标记节点是否访问过 
int n,block=0;//节点数,连通块数
int maxdepth[N],depth[N];//maxdepth记录每个节点的最大深度,depth记录到root的距离 
void DFS(int v,int root){
	flag[v]=true;
	for(int i:G[v]){
		if(!flag[i]){
			depth[i]=depth[v]+1;//当前结点深度为其父节点深度+1
            maxdepth[root]=max(maxdepth[root],depth[i]);//更新树的深度
            DFS(i,root);
		}
	}
}
int main(){
	cin>>n;
	int a,b; 
	for(int i=1;i<n;i++){//输入n-1条边 
		scanf("%d %d",&a,&b);
		G[a].push_back(b);
		G[b].push_back(a);
	}
	for(int i=1;i<=n;i++){
		if(!flag[i]){
			DFS(i,i);
			block++;
		}
	}
	if(block>1){
		printf("Error: %d components\n",block);
	}else{
		for(int i=2;i<=n;i++){//i=1必然遍历过了
            memset(depth,0,sizeof(depth));
            memset(flag,false,sizeof(flag));
            DFS(i,i);
        }
        vector<int> ans;//存储为根节点时使树的深度最大的结点
        int deep=0;//查找所有为根节点时使树的深度最大的结点
        for(int i=1;i<=n;i++)
            if(maxdepth[i]>deep){
                ans.clear();
                ans.push_back(i);
                deep=maxdepth[i];
            }else if(maxdepth[i]==deep)
                ans.push_back(i);
        for(int i:ans)printf("%d\n",i);
	}
    return 0;
}
Publicados 177 artículos originales · ganado elogios 5 · Vistas 6656

Supongo que te gusta

Origin blog.csdn.net/a1920993165/article/details/105555810
Recomendado
Clasificación