1. 程式人生 > >【2018 ICPC亞洲區域賽沈陽站 L】Tree(思維+dfs)

【2018 ICPC亞洲區域賽沈陽站 L】Tree(思維+dfs)

lan n-n desc direct i++ scrip title between win

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種顏色,先用這K種顏色染色。將連通相同顏色的點所需要的最少數量的邊作為一個集合(其實也就類似於一種最小生成樹),然後將所有顏色所形成的集合樹做一個交集,現在要找到一種染色方案,使得這個交集最大。若不使用某種顏色,那麽該顏色的邊集為空集。

思路:

題意真的好難讀懂呀!看了半天也沒思路!我一開始往點的方向思考,實則不行,必須要往邊的方向想才對。

在給某一種顏色染色時,最好是只染最外邊的兩個點,因為要省出一些點給其他顏色,有空集顏色出現肯定是不好的情況。對於每一條邊,它的兩點分別延伸出去兩棵子樹,所以只要看每一條邊所對應的兩棵子樹大小,是否都大於等於K即可。若滿足條件,則必在交集之中,最後深搜遍歷就好了!

題目鏈接:HDOJ 6228

#include<bits/stdc++.h>
#define MAX 200005
using namespace std;
typedef long long ll;
int n,k,sum,num[MAX];
vector<int>ve[MAX];
void dfs(int x,int next)
{
    num[x]=1;
    int i,j;
    for(i=0;i<ve[x].size();i++)
    {
        int y=ve[x][i];
        if(y==next)continue;
        dfs(y,x);
        num[x]+=num[y];
        if(num[y]>=k&&n-num[y]>=k)
            sum++;
    }
}
int main()
{
    int i,j,T;
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--)
    {
        memset(num,0,sizeof(num));
        cin>>n>>k;
        for(i=1;i<=n;i++)
            ve[i].clear();
        for(i=1;i<n;i++)
        {
            int x,y;
            cin>>x>>y;
            ve[x].push_back(y);
            ve[y].push_back(x);
        }
        sum=0;
        dfs(1,-1);
        cout<<sum<<endl;
    }
    return 0;
}

【2018 ICPC亞洲區域賽沈陽站 L】Tree(思維+dfs)