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 100010
using 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;
}
}