Tree 2017icpc沈阳沈阳站

来源:互联网 发布:centos7 yum chrome 编辑:程序博客网 时间:2024/06/02 07:31

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

题意: 一个有n个节点的树,现在给你k种颜色,让你给每个节点染色(方案自己选),定义Ei为连接第i种颜色的所有节点的边的最小集合(类似于最下生成树)
定义ans=所有E取交集的大小, 要你求出ans的最大值。

对于我来说 题目实在难懂,看了好久。
看懂之后其实很简单。 考虑每条边的贡献 对于每条边链接的两颗子树,如果这两颗子树的大小都大于等于k 那么这条边就是有贡献的。
ans++;
dfs一遍即可

#include<bits/stdc++.h>#define LL long long#define N 100010using namespace std;const int MAX=1e6+10;const int matX = 1e2 + 5;const int mod = 1e9 + 7;class edge {public:    int u,v,next;};edge ed[MAX<<1];int head[MAX];int tot;void add(int u,int v) {    ed[tot].u=u;    ed[tot].v=v;    ed[tot].next=head[u];    head[u]=tot;    tot++;}void init() {    tot=0;    memset(head,-1,sizeof head);}int sizes[MAX];int ans=0;int n,k;void dfs(int u,int per) {    sizes[u]=1;    //cout<<u<<"<-"<<per<<endl;    for(int i=head[u]; i!=-1; i=ed[i].next) {        int v=ed[i].v;        if(v==per) continue;        dfs(v,u);        sizes[u]+=sizes[v];    }    if(sizes[u]>=k && n-sizes[u]>=k) ans++;}int main() {    int T;    scanf("%d",&T);    while(T--) {        init();        memset(sizes,0,sizeof sizes);        ans=0;        scanf("%d %d",&n,&k);        for(int i=1; i<n; i++) {            int u,v;            scanf("%d %d",&u,&v);            add(u,v);            add(v,u);        }        dfs(1,-1);        cout<<ans<<endl;    }}