【1021】Deepest Root (25 分)

简介: 【1021】Deepest Root (25 分)【1021】Deepest Root (25 分)
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<algorithm>  
#include<map>
#include<vector>
#include<queue> 
using namespace std; 
const int N=100010;
vector<int> G[N];//邻接表
bool isRoot[N]; //记录每个结点是否作为某个集合的根结点
int father[N];
int findFather(int x){ //查找x所在结合的根结点
  int a=x;
  while(x !=father[x]){
    x=father[x];
  }
  //路径压缩(可不写)
  while(a != father[a]){
    int z=a;
    a=father[a];
    father[z]=x;
  }
  return x;
}
void Union(int a,int b){ //合并a和b所在的集合
  int faA=findFather(a);
  int faB=findFather(b);
  if(faA != faB){
    father[faA]=faB;
  }
}
void init(int n){ //并查集初始化
  for(int i=1;i<=n;i++){
    father[i]=i;
  }
}
int calBlock(int n){  //计算连通块个数
  int Block=0;
  for(int i=1;i<=n;i++){
    isRoot[findFather(i)]=true;  //i的根结点是findeFather(i)
  }
  for(int i=1;i<=n;i++){
    Block += isRoot[i]; //累加根结点个数
  }
  return Block;
}
int maxH=0; //最大高度
vector<int> temp,Ans; //temp临时存放DFS的最远结果,Ans保存答案
//DFS函数,u为当前访问结点编号,Height为当前树高,pre为u的父结点
void DFS(int u,int Height,int pre){
  if(Height > maxH){  //如果获得了更大的树高
    temp.clear(); //清空temp
    temp.push_back(u);//将当前结点u加入temp中
    maxH=Height; //将最大树高赋给maxH
  }else if(Height == maxH){ //如果树高等于最大树高
    temp.push_back(u); //将当前结点加入temp中
  }
  for(int i=0;i<G[u].size();i++){ //遍历u的所有子结点
    //由于邻接表中存放无向图,因此需要跳回去的边
    if(G[u][i] == pre)  continue;
    DFS(G[u][i] ,Height+1,u) ;//访问子结点
  }
}
int main(){   
  int a,b,n;
  scanf("%d",&n);
  init(n); //并查集初始化
  for(int i=1;i<n;i++){
    scanf("%d%d",&a,&b);
    G[a].push_back(b);  //边a->b
    G[b].push_back(a);  //边b->a
    Union(a,b);  //合并a和b所在的集合
  }
  int Block=calBlock(n); //计算集合数目
  if(Block !=1){ //不止一个连通块
    printf("Error: %d components\n",Block);
  }else{
    DFS(1,1,-1); //从1号结点开始DFS,初始高度为1
    Ans=temp; //temp为集合A,赋给Ans
    DFS(Ans[0],1,-1); //从任意一个根结点开始遍历
    for(int i=0;i<temp.size();i++){ 
      Ans.push_back(temp[i]) ;//此时temp为集合B,将其加到Ans中
    }
    sort(Ans.begin(),Ans.end()); //按编号从小到大排序
    printf("%d\n",Ans[0]);
    for(int i=1;i<Ans.size();i++){
      if(Ans[i]!=Ans[i-1]){  //重复编号不输出
        printf("%d\n",Ans[i]);
      }
    }
  }
  system("pause"); 
    return 0;   
}
相关文章
|
6月前
1043 输出PATest (20 分)
1043 输出PATest (20 分)
|
7月前
|
弹性计算 Shell Linux
|
7月前
|
弹性计算 运维 Shell
统计/etc/passwd 中 root 出现的次数
【4月更文挑战第29天】
38 0
|
7月前
|
弹性计算 Shell Linux
|
7月前
|
弹性计算 运维 Shell
统计/etc/passwd 中root 出现的次数
【4月更文挑战第29天】
64 0
|
Unix Linux API
不是root,功能却超过root的手机软件
这篇文章介绍了一款名为Shizuku的手机软件,它可以在没有root权限的情况下,允许用户获得超越root权限的功能。该软件是一款开源应用工具,可以让用户更方便地使用系统API,并提升应用的实用效率。它适用于任何手机,无论是否经过root处理。有需要的用户可以下载使用。
432 0
|
Apache
分分钟学会httpd服务
1.安装httpd,并将访问apache服务器的首页修改为hello.html, 且内容为: “My Home Page is hello”
112 0
PTA 1043 输出PATest (20 分)
给定一个长度不超过 10 4 的、仅由英文字母构成的字符串。请将字符重新调整顺序,按 PATestPATest.... 这样的顺序输出,并忽略其它字符。
78 0
082.具有abcd=(ab+cd)2性质的数
082.具有abcd=(ab+cd)2性质的数
111 0
7-1 输出从1加到N的和 (9 分)
7-1 输出从1加到N的和 (9 分)
107 0