北京市商汤科技开发有限公司面向青少年研发了一款智能伴游机器人-- AI 伴游小精灵。一经推出,深受孩子们的喜爱,可爱又机智的小精灵会想出很多有趣的小游戏
来启迪孩子们思考。今天,小精灵给你提出了一个神奇又有趣的多米诺骨牌小游戏。
你手上有一副神奇的多米诺骨牌,数量有 n 个,编号为 1∼n 。它们之间存在着 n−1 个单向推倒关系,即推倒 x 会导致 y 也被推倒,而且这样的关系都满足 x<y,且每组关系中的 y 不会重复。
一开始只有 1 号骨牌不会被其他骨牌推倒,所以你只需要推倒 1 号骨牌就可以推倒所有的骨牌。
小精灵给你提的问题是:如果我们允许去掉 2 个骨牌,那么在最坏情况下你最少需要推倒几个骨牌才能使所有骨牌倒下?
输入格式
第一行输入一个整数 n,表示有 n 个多米诺骨牌。
接下来有 n−1行的输入,每行输入两个整数 x,y,表示推倒 x 会导致 y 也被推倒。
输出格式
输出一个整数表示去掉两个骨牌之后,最坏情况下你最少需要推倒几个骨牌才能使所有骨牌倒下。
数据规模
n≤5×10^3
样例输入
7 1 2 1 3 1 5 2 4 4 7 4 6
样例输出
5
因为一开始只有1号骨牌不会被其他骨牌推倒,所以一开始是一棵树。去掉两个节点,变成森林,问你这个森林里最多有多少棵树。首先找出连接的边最多的节点(如果是1号节点就是它孩子的个数,其他节点是孩子的个数+1),假设连接这个节点的边数为 a,那么去掉这个节点使得森林里有 a 棵树。同时连接它的孩子节点的边减少一条,再次遍历找到连接的边最多的节点,假设为 b,去掉这个节点使得该节点所在的树变为有 b 棵树的森林。
因此答案是 a+b-1
#include <iostream>
#include <vector>
using namespace std;
vector<int> v[50007];
int main(){
int n;
int x,y,ans = 0;
int cnt[50007];
cin >> n;
for(int i = 0;i < n-1;i++){
cin >> x >> y;
cnt[x]++;
cnt[y]++;
v[x].push_back(y);
v[y].push_back(x);
}
int max = 0,maxx = 0;
for(int i = 1;i<=n;i++){
if(cnt[max]<cnt[i]){
max = i;
}
}
ans+=cnt[max];
cnt[max] = 0;
for(int i = 0;i < v[max].size();i++){
cnt[v[max][i]]--;
}
for(int i = 1;i<=n;i++){
if(cnt[maxx]<cnt[i]){
maxx = i;
}
}
ans+=cnt[maxx];
cout << ans-1;
}