北京市商汤科技开发有限公司面向青少年研发了一款智能伴游机器人-- AI 伴游小精灵。一经推出,深受孩子们的喜爱,可爱又机智的小精灵会想出很多有趣的小游戏来启迪孩子们思考。今天,小精灵给你提出了一个神奇又有趣的多米诺骨牌小游戏。
你手上有一副神奇的多米诺骨牌,数量有 nn个,编号为 1 \sim n1∼n。它们之间存在着 n-1n−1 个单向推倒关系,即推倒 xx 会导致 yy 也被推倒,而且这样的关系都满足 x<yx<y,且每组关系中的 yy 不会重复。
一开始只有 11 号骨牌不会被其他骨牌推倒,所以你只需要推倒 11 号骨牌就可以推>倒所有的骨牌。
小精灵给你提的问题是:如果我们允许去掉 22个骨牌,那么在最坏情况下你最少需要推倒几个骨牌才能使所有骨牌倒下?
输入格式
第一行输入一个整数 nn,表示有 nn 个多米诺骨牌。
接下来有 n-1n−1 行的输入,每行输入两个整数 x,yx,y,表示推倒 xx 会导致 yy 也被推倒。
输出格式
输出一个整数表示去掉两个骨牌之后,最坏情况下你最少需要推倒几个骨牌才能使所有骨牌倒下。
数据规模
n≤5×10^3
样例输入复制
7
1 2
1 3
1 5
2 4
4 7
4 6
样例输出复制
5
每组关系中的 y 不会重复很关键
一个点删去后,它连的点都要推到,有用的是它的出度
所以答案是出度最大的两个点。
特殊情况:
1:其中一个点是1,因为1本来要推到,现在不用了(删了),ans-1。
2:这两个点有边,ans-1,(后面那个点没了)
所以枚举最大和次大值,防止答案差1.
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n;
int per[5009];
int v[5009],a[5009],du[5009];
bool cmp(const int &a,const int &b) {
return du[a] > du[b];
}
int main() {
scanf("%d",&n);
for (int i = 1,a,b; i < n; i++) {
scanf("%d%d",&a,&b);
per[b] = a;
du[a]++;
}
du[1]--;
int sum = 0;
for (int i = 1; i < n; i++) a[i] = i;
sort(a+1,a+n+1,cmp);
int ans = 0;
for (int i = 1; du[a[i]]==du[a[1]]; i++)
for (int j = i+1; du[a[j]]==du[a[i+1]]; j++)
ans = max(ans,1-(per[a[i]]==a[j])-(per[a[j]]==a[i])+du[a[i]]+du[a[j]]);
printf("%d",ans);
return 0;
}