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; }
时间: 2024-11-03 21:16:39