• POJ 3107 Godfather (树形dp)


    题目链接

    虽然题目不难,但是1A还是很爽, 只是刚开始理解错题意了,想了好久。 还有据说这个题用vector会超时,看了以后还是用邻接吧。

    题意:

    给一颗树,保证是一颗树,求去掉一个点以后的联通块里节点的数目的 最大值最小,求这样的点,并按照递增顺序输出。

    分析:

    d[father] = max(n-sum, d[son]);   sum代表这个节点以下的全部节点总数, 去掉一个节点的联通块的最大的节点数 等于 整个树里的节点数减去这个节点下的总数 和 子树的数目的

    最大值。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <vector>
     8 #define LL __int64
     9 const int maxn = 50000+10;
    10 const int INF = 1<<28;
    11 using namespace std;
    12 int head[maxn], vis[maxn], t, d[maxn];
    13 int mi, n;
    14 struct node
    15 {
    16     int u, v, ne;
    17 }e[2*maxn];
    18 
    19 void add(int u, int v)
    20 {
    21     e[t].u = u;
    22     e[t].v = v;
    23     e[t].ne = head[u];
    24     head[u] = t++;
    25 }
    26 int dfs(int son, int fa)
    27 {
    28     int i, tmp, sum = 1, x;  //sum是以son为根节点的子树的全部的节点数
    29     for(i = head[son]; i != -1; i = e[i].ne)
    30     {
    31         tmp = e[i].v;
    32         if(tmp == fa) continue;  //避免回去。
    33         x = dfs(tmp, son);
    34         sum += x;
    35         d[son] = max(d[son], x);
    36     }
    37     d[son] = max(d[son], n-sum);
    38     if(d[son]<mi)
    39     mi = d[son];
    40     return sum;
    41 }
    42 int main()
    43 {
    44     int i, f;
    45     while(~scanf("%d", &n))
    46     {
    47         memset(e, 0, sizeof(e));
    48         memset(head, -1, sizeof(head));
    49         memset(vis, 0, sizeof(vis));
    50         memset(d, 0, sizeof(d));
    51         t = 0;
    52         mi = INF;
    53 
    54         for(i = 1; i < n; i++)
    55         {
    56             int u, v;
    57             scanf("%d%d", &u, &v);
    58             add(u, v);
    59             add(v, u);
    60         }
    61         dfs(1, -1);  //把给的树看成以1为根节点。
    62 
    63         f = 0;
    64         for(i = 1; i <= n; i++)
    65         {
    66            if(d[i]==mi)
    67            {
    68                if(f)
    69                printf(" %d", i);
    70                else
    71                printf("%d", i);
    72                f = 1;
    73            }
    74         }
    75         printf("
    ");
    76     }
    77     return 0;
    78 }

    避免回去的时候也可以用vis[]来标记

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <vector>
     8 #define LL __int64
     9 const int maxn = 50000+10;
    10 const int INF = 1<<28;
    11 using namespace std;
    12 int head[maxn], vis[maxn], t, d[maxn];
    13 int mi, n;
    14 struct node
    15 {
    16     int u, v, ne;
    17 }e[2*maxn];
    18 
    19 void add(int u, int v)
    20 {
    21     e[t].u = u;
    22     e[t].v = v;
    23     e[t].ne = head[u];
    24     head[u] = t++;
    25 }
    26 int dfs(int son)
    27 {
    28     int i, tmp, sum = 1, x;
    29     vis[son] = 1;
    30     for(i = head[son]; i != -1; i = e[i].ne)
    31     {
    32         tmp = e[i].v;
    33         if(vis[tmp]) continue;
    34         x = dfs(tmp);
    35         sum += x;
    36         d[son] = max(d[son], x);
    37     }
    38     d[son] = max(d[son], n-sum);
    39     if(d[son]<mi)
    40     mi = d[son];
    41     return sum;
    42 }
    43 int main()
    44 {
    45     int i, f;
    46     while(~scanf("%d", &n))
    47     {
    48         memset(e, 0, sizeof(e));
    49         memset(head, -1, sizeof(head));
    50         memset(vis, 0, sizeof(vis));
    51         memset(d, 0, sizeof(d));
    52         t = 0;
    53         mi = INF;
    54 
    55         for(i = 1; i < n; i++)
    56         {
    57             int u, v;
    58             scanf("%d%d", &u, &v);
    59             add(u, v);
    60             add(v, u);
    61         }
    62         dfs(1);
    63 
    64         f = 0;
    65         for(i = 1; i <= n; i++)
    66         {
    67            if(d[i]==mi)
    68            {
    69                if(f)
    70                printf(" %d", i);
    71                else
    72                printf("%d", i);
    73                f = 1;
    74            }
    75         }
    76         printf("
    ");
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    MFC程序自动生成dump Windbg文件
    .net 播放音频(使用winmm.dll)
    media player 网页代码属性
    标记ATL控件为安全控件
    js方法重写
    cab包inf文件配置
    凌阳单片机(61板)USB下载线原理与制作
    html 智能检查,修复
    差异性发展 浙江工商局长郑宇民“智斗”央视女主持董倩
    什么是有效高效的沟通
  • 原文地址:https://www.cnblogs.com/bfshm/p/3964044.html
Copyright © 2020-2023  润新知