• 【赛后补题】(HDU6228) Tree {2017-ACM/ICPC Shenyang Onsite}


    这条题目当时卡了我们半天,于是成功打铁……今天回来一看,mmp,贪心思想怎么这么弱智。。。。。(怪不得场上那么多人A了

    题意分析

    这里是原题:

    Tree

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)

    Problem Description
    Consider a un-rooted tree T which is not the biological significance of tree or plant, but a tree as an undirected graph in graph theory with n nodes, labelled from 1 to n. If you cannot understand the concept of a tree here, please omit this problem.
    Now we decide to colour its nodes with k distinct colours, labelled from 1 to k. Then for each colour i = 1, 2, · · · , k, define Ei as the minimum subset of edges connecting all nodes coloured by i. If there is no node of the tree coloured by a specified colour i, Ei will be empty.
    Try to decide a colour scheme to maximize the size of E1 ∩ E2 · · · ∩ Ek, and output its size.

    Input
    The first line of input contains an integer T (1 ≤ T ≤ 1000), indicating the total number of test cases.
    For each case, the first line contains two positive integers n which is the size of the tree and k (k ≤ 500) which is the number of colours. Each of the following n - 1 lines contains two integers x and y describing an edge between them. We are sure that the given graph is a tree.
    The summation of n in input is smaller than or equal to 200000.

    Output
    For each test case, output the maximum size of E1 ∩ E1 … ∩ Ek.

    Sample Input
    3
    4 2
    1 2
    2 3
    3 4
    4 2
    1 2
    1 3
    1 4
    6 3
    1 2
    2 3
    3 4
    3 5
    6 2

    Sample Output
    1
    0
    1

    题意很简单,我们考虑一下做法。
    要想交集尽可能大,颜色各自的分布应该尽可能“往顶层和底层分布”——这是贪心思想。然后具体怎么实现?很简单,对每一个点i,设它的子树的节点(包括它自身)有p个,那么只需要检查pknpk即可。不需要查边,只需要查点,因为只要存在这样的点,那么一定存在这样的一条公共边。
    实现查子树可以用dfs遍历一遍即可实现。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    #define NQUICKIO
    #define NFILE
    
    struct Edge
    {
        int u,v;
        Edge(int _u,int _v):u(_u),v(_v) {}
    };
    const int maxnode=200005;
    vector<Edge> edges;
    vector<int> G[maxnode];
    int s[maxnode];
    void addEdge(int u,int v)
    {
        edges.push_back(Edge(u,v));
        G[u].push_back((int)edges.size()-1);
        return;
    }
    
    int dfs(int f,int p)
    {
        //cout<<"now point:"<<p<<endl;
        int nowsum=1;
        for(int i=0;i!=(int)G[p].size();++i)
            if(edges[G[p][i]].v!=f)
                nowsum+=dfs(p,edges[G[p][i]].v);
        return s[p]=nowsum;
    }
    
    int main()
    {
    #ifdef QUICKIO
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
    #endif
    #ifdef FILE
        freopen("datain.txt","r",stdin);
        freopen("dataout.txt","w",stdout);
    #endif
        int T; cin>>T;
        while(T--)
        {
            edges.clear();
            int n,k; cin>>n>>k;
            for(int i=1;i<=n;++i) G[i].clear();
            memset(s,0,sizeof(s));
            for(int i=1;i!=n;++i)
            {
                int tu,tv; cin>>tu>>tv;
                addEdge(tu,tv);
                addEdge(tv,tu);
            }
            dfs(-1,edges[0].u);
            int ans=0;
            /*for(int i=1;i<=n;++i)
                cout<<s[i]<<" ";
                cout<<endl;*/
            for(int i=1;i<=n;++i)
            {
                if(s[i]>=k && n-s[i]>=k) ans++;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    
    如非注明,原创内容遵循GFDLv1.3发布;其中的代码遵循GPLv3发布。
  • 相关阅读:
    EF Core 打印日志
    生成各种开源挂件的网址
    .NET Core 原生 Aop,不依赖任何第三方
    .NET Core + Castle.DynamicProxy 拦截
    EF Core 审计日志
    Gitee 接口大全
    VS 批量新增文件头
    Linq 完全指南
    swagger转word
    大型网站架构
  • 原文地址:https://www.cnblogs.com/samhx/p/9652100.html
Copyright © 2020-2023  润新知