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 }
  • 相关阅读:
    月薪 30K Java 程序员,需要掌握哪些技术?
    docker-compose安装mongodb
    docker-compose安装apollo服务
    docker-compose安装mysql和redis
    编程总结1:打印沙漏
    秋季学习总结
    对我人生影响最大的三位老师
    自我介绍
    秋季学习总结
    人生路上对我影响最大的三位老师
  • 原文地址:https://www.cnblogs.com/zxhyxiao/p/7784372.html
Copyright © 2011-2022 走看看