zoukankan      html  css  js  c++  java
  • POJ3107 Godfather (树形DP)

    题意:求树的重心

    题解:先跑一遍dfs 预处理出这种遍历方式每个节点的儿子(含自己)的数

       再跑一遍 每个点的值就是他所有儿子中取一个最大值 再和它父亲这个方向比较一下

       又被卡常了 vector一直tle 需要用前向星....

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #include <string.h>
    using namespace std;
    
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    struct node
    {
        int no, to, nex;
    }E[100005];
    
    int n, rt;
    int du[50005];
    int head[50005];
    int son[50005];
    int dp[50005];
    
    int dfs1(int x, int fa)
    {
        son[x] = 1;
        int c = head[x];
        for(int i = c; i; i = E[i].nex)
        {
            int c = E[i].to;
            if(c == fa) continue;
    
            son[x] += dfs1(c, x);
        }
        return son[x];
    }
    
    void dfs2(int x, int fa)
    {
        dp[x] = n - son[x];
        int c = head[x];
        for(int i = c; i; i = E[i].nex)
        {
            int c = E[i].to;
            if(c == fa) continue;
    
            dp[x] = max(dp[x], son[c]);
            dfs2(c, x);
        }
    }
    
    int main()
    {
        while(~scanf("%d", &n))
        {
            for(int i = 1; i <= n; i++) du[i] = son[i] = dp[i] = head[i] = 0;
    
            int cn = 0;
            for(int i = 1; i < n; i++)
            {
                int u, v;
                u = read(); v = read();
                E[++cn].no = u;
                E[cn].to = v;
                E[cn].nex = head[u];
                head[u] = cn;
    
                E[++cn].no = v;
                E[cn].to = u;
                E[cn].nex = head[v];
                head[v] = cn;
                du[u]++;
                du[v]++;
            }
    
    
            for(int i = 1; i <= n; i++)
                if(du[i] == 1)
                {
                    rt = i;
                    break;
                }
    
            int o = dfs1(rt, -1);
            dfs2(rt, -1);
    
            int ans = n + 5;
            int cnt = 0;
            for(int i = 1; i <= n; i++) ans = min(ans, dp[i]);
            for(int i = 1; i <= n; i++)
                if(dp[i] == ans) cnt++;
    
            for(int i = 1; i <= n; i++)
            {
                if(dp[i] == ans)
                {
                    if(cnt == 1)
                    {
                        printf("%d
    ", i);
                        break;
                    }
                    else printf("%d ", i);
                    cnt--;
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Latex学习
    【测试】安卓自动化测试代码片段Java
    【测试】adb(Android debug bridge译名:安卓测试桥)的介绍与常用命令
    【测试】安卓开发中常用的布局和UI元素
    mac终端命令大全
    【测试】使用UIAutomatorViewer做App元素探测工作
    【测试】adb连接夜神模拟器
    mac版本夜神模拟器卡99的解决办法
    mac电脑查看apk文件的包名等信息
    新版macbook pro 取消/恢复开盖启动 revert
  • 原文地址:https://www.cnblogs.com/lwqq3/p/9010935.html
Copyright © 2011-2022 走看看