[POJ1655]Balancing Act

思路:
DP求树的重心。
对于每个结点$i$,$d_i=displaystyle{sum_{jin s(i)}}d_j+1$。
删去这个点能得到的最大子树大小即为$max(maxlimits_{jin s(i)}{d(j)},n-d(i))$。
然后取最小的结点即可。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<vector>
 4 #include<cstring>
 5 inline int getint() {
 6     char ch;
 7     while(!isdigit(ch=getchar()));
 8     int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 const int inf=0x7fffffff;
13 const int V=20001;
14 std::vector<int> e[V];
15 inline void add_edge(const int u,const int v) {
16     e[u].push_back(v);
17 }
18 int id,minsize,size[V];
19 inline void init() {
20     for(int i=0;i<V;i++) e[i].clear();
21     id=minsize=inf;
22     memset(size,0,sizeof size);
23 }
24 int n;
25 void DFS(const int x,const int par) {
26     size[x]=1;
27     int max=0;
28     for(unsigned i=0;i<e[x].size();i++) {
29         int &y=e[x][i];
30         if(y==par) continue;
31         DFS(y,x);
32         size[x]+=size[y];
33         max=std::max(max,size[y]);
34     }
35     max=std::max(max,n-size[x]);
36     if(max<minsize) {
37         minsize=max;
38         id=x;
39     }
40     else if(max==minsize&&x<id) {
41         id=x;
42     }
43 }
44 int main() {
45     for(int T=getint();T;T--) {
46         init();
47         n=getint();
48         for(int i=1;i<n;i++) {
49             int u=getint(),v=getint();
50             add_edge(u,v);
51             add_edge(v,u);
52         }
53         DFS(1,0);
54         printf("%d %d
",id,minsize);
55     }
56     return 0;
57 }
原文地址:https://www.cnblogs.com/skylee03/p/7441218.html