constint N =1e5+10, M =2*N;int h[N], e[M], ne[M];// h[N]: 顶点Ni的第一个连接点bool visited[M];// 某一连接点是否已被搜索int n =0, idx =0;voidadd(int a,int b)// 添加一条边a->b{
e[idx]= b;// 创建相连点b
ne[idx]= h[a];// 该相连点b的下一点是当前顶点a的第一个连接点
h[a]= idx++;// 更新顶点a的第一个连接点}voiddfs(int u){
cout << u <<" ";
visited[u]=true;for(int i = h[u]; i !=-1; i = ne[i]){int j = e[i];if(!visited[j])dfs(j);}}intmain(){memset(h,-1,sizeof h);// 将h置为-1,表示初始时
cin >> n;// 所有顶点都没有连接点int a, b;for(int i =0; i < n -1;++i)// n - 1条无向边{
cin >> a >> b;add(a, b);add(b, a);}dfs(1);return0;}
AcWing 846. 树的重心
无向图
主要找删除某个顶点后各连通块中点个数量的关系
连通点数是个数
constint N =1e5+10, M =2*N;int h[N], e[M], ne[M];// h[N]: 顶点Ni的第一个连接点bool visited[M];// 某一连接点是否已被搜索int n =0, idx =0;voidadd(int a,int b)// 添加一条边a->b{
e[idx]= b;// 创建相连点b
ne[idx]= h[a];// 该相连点b的下一点是当前顶点a的第一个连接点
h[a]= idx++;// 更新顶点a的第一个连接点}int ans = N;// 删除一个顶点后,剩余连通块中点个数的最大值包括// 深搜当前顶点所有未搜索的子连通块和已经搜索过的父连通块intdfs(int u){
visited[u]=true;int sum =1;// 当前顶点的所有连接点个数(包含当前顶点)int ret =0;// 当前顶点各支路的连接点个数的最大值for(int i = h[u]; i !=-1; i = ne[i]){int j = e[i];if(!visited[j]){int tmp =dfs(j);// 利用深度优先遍历获得子树点各个数
ret =max(ret, tmp);// 这里得到当前顶点各子连通块最大点个数
sum += tmp;// 同时也累加了各子连通块的点的个数}}
ret =max(ret, n - sum);// 获得当前顶点父路径连通块的点个数,同时获得最大点个数
ans =min(ans, ret);return sum;}intmain(){memset(h,-1,sizeof h);// 将h置为-1,表示初始时
cin >> n;// 所有顶点都没有连接点int a, b;for(int i =0; i < n -1;++i)// n - 1条无向边{
cin >> a >> b;add(a, b);add(b, a);}dfs(1);
cout << ans;return0;}