树和图的深度优先遍历

给定一颗树,树中包含n个结点(编号1~n)和n-1条无向边。

请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。

重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中点数的最大值最小,那么这个节点被称为树的重心。

输入格式

第一行包含整数n,表示树的结点数。

接下来n-1行,每行包含两个整数a和b,表示点a和点b之间存在一条边。

输出格式

输出一个整数m,表示重心的所有的子树中最大的子树的结点数目。

数据范围

1n1051≤n≤105

输入样例

9
1 2
1 7
1 4
2 8
2 5
4 3
3 9
4 6

输出样例:

4

######################################################################

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e5+10;
 5 const int M = 2*(1e5+10);
 6 
 7 vector<int> h(N,-1), e(M,-1), ne(M,0);
 8 vector<bool> f(N,false);
 9 int n;
10 int idx = 0;
11 int ans = N;
12 
13 //在a顶点后面连接b
14 void add(int a, int b){
15     e[idx] = b;        
16     ne[idx] = h[a];
17     h[a] = idx++;
18 }    
19 //返回以当前节点为根节点的节点个数
20 int dfs(int u){
21     f[u] = true;//标记访问过  
22     int sum = 1;//代表根节点那一个节点
23     int size = 0, res = 0;//ans用来求没有当前根结点往下的每一个联通块中最大的联通块的数目 
24     for(int i = h[u];i != -1;i = ne[i]){
25         int t = e[i];
26         if(!f[t]){
27             size = dfs(t);
28             res = max(res, size);
29             sum += size;
30         }
31     }
32     res = max(res, n - sum);    
33     ans = min(ans, res);
34     return sum;
35 }
36 int main(){
37     cin >> n;     
38     for(int i = 0;i < n-1;++i){
39         int a, b;
40         cin >> a >> b;
41         add(a, b); add(b, a);
42     }
43     dfs(1);
44     cout << ans << endl;
45     return 0;
46 }
View Code

猜你喜欢

转载自www.cnblogs.com/sxq-study/p/12233082.html