HDU - 6228 Tree (dfs)

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.

InputThe 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.

OutputFor 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

分析:  问题可以转化为求有多少条边左右两边都有k个以上的点。因为这样的边一定是符合要求的。题目保证这是一个树,树是无向无环图,所以我们可以从一个点开始DFS搜索,进而找到每一个点左右两边的点数

代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
const int MAXN=2e5+10;
int vis[MAXN];
int num[MAXN];
int cnt;
vector<int>V[MAXN];
struct node
{
    int u;
    int v;
}poi[MAXN];
 int t,n,k,a,b,ans;
void dfs(int x)
{
    int u,v;
    num[x]=1;
  for(int i=0;i<V[x].size();i++)
  {
          u=x;
          v=V[x][i];
     /*     if(v==pre)
            continue;*/
          if(!vis[v])
          {
            vis[v]=1;
          dfs(v);
          num[u]+=num[v];
          }
  }
    if(num[u]>=k&&n-num[u]>=k)
         ans++;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
      memset(vis,0,sizeof(vis));
        ans=0;
        scanf("%d%d",&n,&k);
        for(int i=0;i<=n;i++)V[i].clear();
         int h=n-1;
         for(int i=0;i<n-1;i++){
            scanf("%d%d",&poi[i].u,&poi[i].v);
            V[poi[i].u].push_back(poi[i].v);
            V[poi[i].v].push_back(poi[i].u);
         }
         vis[1]=1;
        dfs(1);
        printf("%d\n",ans);
    }
    return 0;
}
				
时间: 2024-07-31 03:04:19

HDU - 6228 Tree (dfs)的相关文章

hdu 6228 Tree

hdu 6228 题意:一棵 n 个点的树,要你把这些树上的节点用 k 种颜色染色,问你在最优的染色方案下,相同颜色点连接的最小边集的交集最大是多少 Tags: dfs,  貌似读懂题就好做了.. #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b;

HDU 6228 Tree(思维 DFS)

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

HDU 6228 tree 简单思维树dp

一.前言 前两天沈阳重现,经过队友提点,得到3题的成绩,但是看到这题下意识觉得题目错了,最后发现实际上是题目读错了....GG 感觉自己前所未有的愚蠢了....不过题目读对了也是一道思维题,但是很好理解. 二.题意 对于一个无相无环图,要求找出若干边,满足"这些边被至少K个不同的点集在互相联通的时候访问到".或者说"这些边都包含在K个不同的点集个字组成的联通快里面". 三.题解 考虑如何表示一个边,以及这条边两边的点的数量?(这是一棵树)作为一颗树,就有树边概念,因

hdu 2489 Minimal Ratio Tree(dfs枚举 + 最小生成树)~~~

题目: 链接:点击打开链接 题意: 输入n个点,要求选m个点满足连接m个点的m-1条边权值和sum与点的权值和ans使得sum/ans最小,并输出所选的m个点,如果有多种情况就选第一个点最小的,如果第一个点也相同就选第二个点最小的........ 思路: 求一个图中的一颗子树,使得Sum(edge weight)/Sum(point weight)最小~ 数据量小,暴力枚举~~~~~dfs暴力枚举C(M,N)种情况. 枚举出这M个点之后,Sum(point weight)固定,进行prim或者K

hdu 5293 Tree chain problem(树链剖分+树形dp)

题目链接:hdu 5293 Tree chain problem 维护dp[u], sum[u],dp[u]表示以u为根节点的子树的最优值.sum[u]表示以u节点的所有子节点的dp[v]之和.对于边a,b,w,在LCA(a,b)节点的时候进行考虑.dp[u] = min{dp[u], Sum(a,b) - Dp(a,b) + sum[u] | (ab链上的点,不包括u } #pragma comment(linker, "/STACK:1024000000,1024000000")

hdu 4757 Tree(可持久化字典树)

题目链接:hdu 4757 Tree 题目大意:给定一棵树,每一个节点有一个值.如今有Q次询问,每次询问u到v路径上节点值与w亦或值的最大值. 解题思路:刚開始以为是树链剖分,事实上树链剖分仅仅是用来求LCA(能够不用树链剖分). 可持久化字典树.在每次插入的同一时候,不改动原先的节点.而是对全部改动的节点复制一个新的节点,而且在新的节点 上做操作,这样做的目的是可以获取某次改动前的状态.同过可持久化的操作,保留了改动前后的公共数据. 对给定树上的全部节点权值建立01字典树,然后每一个节点都保存

hdu 3534 Tree(树形DP)

题目链接:hdu 3534 Tree 题意: 给你一棵n个节点,n-1条边的树,每条边有一个长度,现在问你最长的边的长度为多少,有多少条. 题解: 其实这种题不用记录最长和次长,我们开两个数组,len[i],num[i]. 表示以i为根结点出发的最长的长度以及最长的边的条数. 然后我们只需要一个dfs,先用子节点的信息来更新答案,然后在更新当前节点的len和num记录的信息. 这样就不用记录最长和次长. 1 #include<bits/stdc++.h> 2 #define mst(a,b)

hdu 5370 Tree Maker(catalan+dp)

题目链接:hdu 5370 Tree Maker n个节点的二叉树种类为Catalan数的第n项 对于一棵子树而言,被移动过的节点就是确定的位置,所以只要知道已经确定位置的K个节点有多少个空孩子指针M,和就该子树下的N个未确定位置的节点,等于是说用N个节点构造M个可为空的子树的种类数.对于整个树的形态数即为若干棵独立的子树形态数的乘积. 定义dp[i][j]为用i个节点构造j棵树的形态数,dp[i][j] = sum{ dp[i-1][j-k] * catalan[k] | 0 ≤ k ≤j }

HDU 5044 Tree(树链剖分)

HDU 5044 Tree 题目链接 就简单的树链剖分,不过坑要加输入外挂,还要手动扩栈 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 100005; #pragma comment(linker, "/STACK:1024000000,1024000000"