持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情
本文已参与「新人创作礼」活动,一 起开启掘金创作之路。
题目链接
题目
题目分析
就是让我们去找一个树状结构如下图
只需要中间节点的值大于两侧节点那么是肯定可以操作一次的
所以我们以大结点向小节点连边
所以我们只需遍历这个节点与之两边的点看是否有超过两个长度大于一的点在此过程中我们用并查集去维护与此点相连并且小于该点的个数即可
Code
vector<int> v[N];
int f[N];
int siz[N];
int find(int x) { return f[x] == x ? f[x] : f[x] = find(f[x]);}
void solve()
{
int n; cin >> n;
rep(i,n) v[i].clear();
rep(i,n) f[i] = i,siz[i] = 1;
int res = 0;
rep(i,n - 1) {
int x,y; cin >> x >> y;
v[max(x,y)].pb(min(x,y));
}
rep(i,n) {
int cnt = 0;
for(auto u : v[i]) {
int fa = find(i);
int fb = find(x);
if(siz[fb] >= 1) cnt ++;
siz[fa] += siz[fb];
f[find(x)] = fa;
}
if(cnt >= 2) res ++,siz[find(i)] -= 3;
}
cout << res << endl;
}