zoukankan      html  css  js  c++  java
  • poj2378

    题意:给一棵n个节点的无根树,问去掉那一点可以使各连通分支中的节点数均<=n/2。

    分析:任意选定一个根,用自底向上的方法记录每棵子树的节点数。这样对于每个节点就可以通过它子树的节点数量迅速地判断它是否符合条件,别忘了还要判断它上面那个它祖宗所在的连通分支(节点数为n减去其各个子树的连通分支数再减1)。

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define maxn 10005
    
    struct Edge
    {
        int v, next;
    } edge[maxn * 2];
    
    struct Point
    {
        int id, degree;
    } point[maxn];
    ;
    
    int n, ncount;
    int layer[maxn];
    int head[maxn];
    bool vis[maxn];
    int q[maxn];
    int num[maxn];
    bool ans[maxn];
    
    bool operator <(const Point &a, const Point &b)
    {
        return a.degree > b.degree;
    }
    
    void addedge(int a, int b)
    {
        edge[ncount].v = b;
        edge[ncount].next = head[a];
        head[a] = ncount++;
    }
    
    void input()
    {
        scanf("%d", &n);
        memset(head, -1, sizeof(head));
        for (int i = 0; i < n - 1; i++)
        {
            int a, b;
            scanf("%d%d", &a, &b);
            a--;
            b--;
            addedge(a, b);
            addedge(b, a);
        }
    }
    
    void bfs()
    {
        int front = 0, rear = 0;
        memset(vis, 0, sizeof(vis));
        q[rear++] = 0;
        vis[0] = true;
        layer[0] = 0;
        while (front != rear)
        {
            int u = q[front++];
            for (int i = head[u]; ~i; i = edge[i].next)
            {
                int v = edge[i].v;
                if (vis[v])
                    continue;
                q[rear++] = v;
                layer[v] = layer[u] + 1;
                vis[v] = true;
            }
        }
    }
    
    void make()
    {
        for (int i = 0; i < n; i++)
        {
            point[i].id = i;
            point[i].degree = layer[i];
        }
    }
    
    void work()
    {
        memset(ans, 0, sizeof(ans));
        for (int i = 0; i < n; i++)
        {
            int u = point[i].id;
            bool ok = true;
            num[u] = 1;
            for (int j = head[u]; ~j; j = edge[j].next)
            {
                int v = edge[j].v;
                if (layer[v] >= layer[u])
                {
                    num[u] += num[v];
                    if (num[v] > n / 2)
                        ok = false;
                }
            }
            if (n - num[u] > n / 2)
                ok = false;
            ans[u] = ok;
        }
        for (int i = 0; i < n; i++)
            if (ans[i])
                printf("%d\n", i + 1);
    }
    
    int main()
    {
        //freopen("t.txt", "r", stdin);
        input();
        bfs();
        make();
        sort(point, point + n);
        work();
        return 0;
    }
  • 相关阅读:
    Python安装的库列表导出到文件和批量安装库文件
    Selenium之浏览器驱动下载和配置使用
    测试面试计算题--python
    软件质量模型
    用例要素和设计方法
    python的层级
    day 14:深浅copy,数据结构 ,函数,set集合,变量作用域、返回值
    day 8:open文件和with的使用
    day 1:计算机发展史和组成部分
    day 2:计算机的基础知识,编程语言分类
  • 原文地址:https://www.cnblogs.com/rainydays/p/2582376.html
Copyright © 2011-2022 走看看