(树的重心)POJ 1655 Balancing Act

题目链接:POJ 1655

 

题目大意:

就是找重心,遇到两个重心,输出编号小的。

 

参考代码:

 1 // 树的重心
 2 // POJ 1655
 3 #include <iostream>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <queue>
 9 #include <vector>
10 #include <stack>
11 #define N 40010
12 #define ll long long
13 using namespace std;
14 int t;
15 int n;
16 int u,v;
17 int cnt;
18 int balance,node; // balance是重心最大子树的节点数,node为重心编号
19 int head[N],nxt[N],to[N],son[N];
20 inline int read()
21 {
22     int x = 0, y = 1; char c = getchar();
23     while(c < '0' || c > '9') {if(c == '-') y = -1; c = getchar();}
24     while(c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
25     return x*y;
26 }
27 void add(int u, int v)
28 {
29     nxt[++cnt] = head[u];
30     head[u] = cnt;
31     to[cnt] = v;
32 }
33 void dfs(int u, int fa)
34 {
35     son[u] = 1;
36     int w = 0; // 注意此处不能定义为全局变量
37     for(int i = head[u]; ~i; i = nxt[i])
38     {
39         int v = to[i];
40         if(v != fa)
41         {
42             dfs(v,u);
43             son[u] += son[v];
44             w = max(w,son[v]);
45         }
46     }
47     w = max(w,n-son[u]); // 向上的节点数
48     if(w < balance)
49     {
50         balance = w;
51         node = u;
52     } else if(w == balance) // 相同,取编号小的
53         node = min(u,node);
54 }
55 void init()
56 {
57     cnt = -1;
58     balance = N+10; // 赋值为较大值
59     memset(head,-1,sizeof(head));
60     memset(son,0,sizeof(son));
61 }
62 int main()
63 {
64     t = read();
65     while(t--)
66     {
67         init();
68         n = read();
69         for(int i = 0; i < n-1; i++)
70         {
71             u = read();
72             v = read();
73             add(u,v);
74             add(v,u);
75         }
76         dfs(1,0);
77         printf("%d %d\n",node,balance);
78     }
79     return 0;
80 }

 

posted @ 2020-11-19 09:28  不敢说的梦  阅读(86)  评论(0)    收藏  举报