树的直径指最长的路径,我们一般求此路径的两个端点,性质,中电的子树节点个数小于等于n/2;

一般两边dfs求取

复制代码
 1 struct edge{
 2     int to;
 3     int w;
 4     int next;
 5 }e[N];
 6 int head[N];
 7 ll dis[N];
 8 ll dis2[N];
 9 int pre[N];
10 int cnt = 0;
11 void add(int v, int u, int w){
12     e[++cnt].w = w;
13     e[cnt].to = u;
14     e[cnt].next = head[v];
15     head[v] = cnt;
16 }
17 int st = 0;
18 int ed = 0;
19 void dfs(int x){
20     for (int i = head[x]; i; i = e[i].next){
21         if (pre[x] != e[i].to){
22             pre[e[i].to] = x;
23             dis[e[i].to] = dis[x] + e[i].w;
24             if (dis[e[i].to] > dis[st])
25                 st = e[i].to;
26             dfs(e[i].to);
27         }
28     }
29 }
30 void dfs2(int x){
31     for (int i = head[x]; i; i = e[i].next){
32         if (pre[x] != e[i].to){
33             pre[e[i].to] = x;
34             dis2[e[i].to] = dis2[x] + e[i].w;
35             if (dis2[e[i].to] > dis2[ed])
36                 ed = e[i].to;
37             dfs2(e[i].to);
38         }
39     }
40 }
41 int main(){
42     int n, m;
43     cin >> n >> m;
44     for (int i = 0; i < m; ++i){
45         int a, b, c;
46         cin >> a >> b >> c;
47         add(a, b, c);
48         add(b, a, c);
49     }
50     dfs(1);
51     memset(pre, 0, sizeof(pre));
52     dfs2(st);
53     cout << st << ' ' << ed;
55     return 0;
56 }//树的直径和两个端点
复制代码

树的重心指一个节点的最大子树最小,性质各点到重心的距离和最短

复制代码
 1 vector<int>e[N];
 2 int s[N];
 3 int pre[N];
 4 int dis[N];
 5 void solve(int x){
 6     s[x] = 1;
 7     for (int a : e[x]){
 8         if (pre[x] != a){
 9             pre[a] = x;
10             solve(a);
11             s[x] += s[a];
12         }
13         
14     }
15 }
16 int main(){
17     int n;
18     cin >> n;
19     for (int i = 0; i < n - 1; ++i){
20         int a, b;
21         cin >> a >> b;
22         e[a].push_back(b);
23         e[b].push_back(a);
24     }
25     pre[1] = -1;
26     solve(1);
27     int dex = 0;
28     int num = (1 << 30);
29     for (int i = 1; i <= n; ++i){
30         int f = 0;
31         for (int a : e[i]){
32             if (pre[i] != a){
33                 f = max(f, s[a]);
34             }
35             else{
36                 f = max(f, n - s[i]);
37             }
38         }
39         if (num >f){
40             num = f;
41             dex = i;
42         }
43     }
44     cout << dex;
45     return 0;
46 }//求树的重心 
复制代码