题目大意:给出一棵n个结点的树以及常数k。将树的所有叶节点(度为1)分组,使得组内每个叶节点距离<=k,求最小组数。
题解:贪心搜索,找一个度不为一的树根,然后对于每个节点按最远的合法叶节点距离排序,然后合并。时间复杂度O(nlogn)。
代码:
#include<vector> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 1000500 int n,k,hed[N],cnt,rt=1,ind[N]; struct EG { int to,nxt; }e[2*N]; void ae(int f,int t) { e[++cnt].to = t; e[cnt].nxt = hed[f]; hed[f] = cnt; } int ans,dis[N]; int dfs(int u,int fa) { if(ind[u]==1)return 0; vector<int>v; for(int j=hed[u];j;j=e[j].nxt) { int to = e[j].to; if(to==fa)continue; int tmp = dfs(to,u)+1; v.push_back(tmp); } sort(v.begin(),v.end()); int ret = v.size()-1; while(ret>0&&v[ret]+v[ret-1]>k){ret--,ans++;if(!ret)break;} return v[ret]; } int main() { scanf("%d%d",&n,&k); for(int f,t,i=1;i<n;i++) { scanf("%d%d",&f,&t); ae(f,t),ae(t,f); ind[f]++,ind[t]++; } while(ind[rt]==1)rt++; dfs(rt,0); printf("%d ",ans+1); return 0; }