HDU6228&&icpc沈阳站思维签到题

http://acm.hdu.edu.cn/showproblem.php?pid=6228

题意:给一颗无根树 给定k种颜色 问用这k种颜色染成的节点形成子树的公共边最大;

题解:刚开始想的通过两遍dfs找最长链的起始和终止位置 然后以起始为根跑dfs统计每个点子树节点个数 然后通过压缩成一个链 从左和从右分别找到两边大于等于k的位置 但是wa了  至今不知道WA在哪 然后想了一下别的思路  一个边能被当作公共边 就必须这个边的两个节点能贡献的子树个数>=k并且(n-子树个数)>=k 然后统计这样的节点有多少个 就是答案;

#include <bits/stdc++.h>
#define N 200005
using namespace std;
vector<int>vec[N];
int num[N];
int ans;int k,n;
void dfs(int u,int pre){
    num[u]=1;
    for(int i=0;i<vec[u].size();i++){
        if(vec[u][i]!=pre){
            dfs(vec[u][i],u);
            num[u]+=num[vec[u][i]];
        }
    }
    if(num[u]>=k&&(n-num[u])>=k) ans++;
}
int main(){
    int T;scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&k);
        for(int i=1;i<n;i++){
            int t1,t2;scanf("%d%d",&t1,&t2);
            vec[t1].push_back(t2);vec[t2].push_back(t1);
        }
        ans=0;
        dfs(1,-1);
        printf("%d\n",ans);
        for(int i=1;i<=n;i++) vec[i].clear();
    }
    return 0;
}

  

posted @ 2017-11-12 00:19  wang9897  阅读(205)  评论(0编辑  收藏  举报