zoukankan      html  css  js  c++  java
  • poj 1655 Balancing Act 求树的重心【树形dp】

    poj 1655 Balancing Act

    题意:求树的重心且编号数最小

    一棵树的重心是指一个结点u,去掉它后剩下的子树结点数最少。

    (图片来源: PatrickZhou 感谢博主)

    看上面的图就好明白了,不仅要考虑当前结点子树的大小,也要“向上”考虑树的大小。

    那么其它就dfs完成就行了,son[] 存以前结点为根的结点个数。

    这是用邻接表写:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn = 20006;
     7 const int INF = 1 << 30;
     8 int head[maxn];
     9 int son[maxn];
    10 bool vis[maxn];
    11 int n,siz, cnt, num;
    12 struct Edge
    13 {
    14     int to, next;
    15 };
    16 Edge edge[maxn*2];
    17 
    18 void Init()
    19 {
    20     memset(vis, 0, sizeof(vis));
    21     memset(head, -1, sizeof(head));
    22     siz =num= INF;
    23     cnt = 0;
    24 }
    25 
    26 
    27 void add(int u, int v)
    28 {
    29     edge[cnt].to = v;
    30     edge[cnt].next = head[u];
    31     head[u] = cnt++;
    32 }
    33 
    34 void dfs(int u)
    35 {
    36     vis[u] = 1;
    37     son[u] = 1;
    38     int tmp = 0;
    39     for (int i = head[u]; i != -1; i = edge[i].next)
    40     {
    41         int v = edge[i].to;
    42         if (!vis[v]) {
    43             dfs(v);
    44             son[u] += son[v];
    45             tmp = max(tmp, son[v]);
    46         }
    47     }
    48     tmp = max(tmp, n - son[u]);
    49     if (tmp < siz || (tmp == siz&&u < num)) {
    50         siz = tmp;
    51         num = u;
    52     }
    53 }
    54 
    55 int main()
    56 {
    57     int T;
    58     cin >> T;
    59     while (T--)
    60     {
    61         cin >> n;
    62         Init();
    63         for (int i = 1; i < n; i++) {
    64             int u, v;
    65             cin >> u >> v;
    66             add(u, v);
    67             add(v, u);
    68         }
    69         dfs(1);
    70         cout << num << " " << siz << endl;
    71     }
    72     return 0;
    73 }

    这题用stl不超时:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<vector>
     5 #include<algorithm>
     6 using namespace std;
     7 const int maxn = 20006;
     8 const int INF = 1 << 30;
     9 vector<int> tree[maxn];
    10 int son[maxn];
    11 int n, siz,num;
    12 
    13 void dfs(int u, int fa)
    14 {
    15     son[u] = 1;
    16     int tmp = 0;
    17     for (int i = 0; i < tree[u].size(); i++) {
    18         int v = tree[u][i];
    19         if (v != fa) {
    20             dfs(v,u);
    21             son[u] += son[v];
    22             tmp = max(tmp, son[v]);
    23         }
    24     }
    25     tmp = max(tmp, n - son[u]);
    26     if ((tmp < siz) || (tmp == siz&&u > num)) {
    27         siz = tmp;
    28         num = u;
    29     }
    30 }
    31 
    32 int main()
    33 {
    34     int T;
    35     cin >> T;
    36     while (T--)
    37     {
    38         cin >> n;
    39         for (int i = 0; i <= n; i++) tree[i].clear();
    40         for (int i = 1; i < n; i++) {
    41             int u, v;
    42             cin >> u >> v;
    43             tree[u].push_back(v);
    44             tree[v].push_back(u);
    45         }
    46         num = 0, siz = INF;
    47         dfs(1, -1);
    48         cout << num << " " << siz << endl;
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    【leetcode】106. Construct Binary Tree from Inorder and Postorder Traversal
    【leetcode】105. Construct Binary Tree from Preorder and Inorder Traversal
    【leetcode】236. Lowest Common Ancestor of a Binary Tree
    【leetcode】235. Lowest Common Ancestor of a Binary Search Tree
    【leetcode】352. Data Stream as Disjoint Intervals
    【leetcode】897. Increasing Order Search Tree
    【leetcode】900. RLE Iterator
    BEC listen and translation exercise 26
    BEC listen and translation exercise 25
    BEC listen and translation exercise 24
  • 原文地址:https://www.cnblogs.com/zxhyxiao/p/7784372.html
Copyright © 2011-2022 走看看