北京市商汤科技开发有限公司面向青少年研发了一款智能伴游机器人-- 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 \le 5 \times 10^3n≤5×10
3
样例输入
7
1 2
1 3
1 5
2 4
4 7
4 6
样例输出
5
思路:找两个出度最多的点,将与这两个点有关的入度都减一,最后找这些入度为0的点的个数。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#define fori(a,b) for(int i=a;i<=b;i++)
#define forj(a,b) for(int j=a;j<=b;j++)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int M=5e3+10;
const int MAX=1e18+10;
const double PI = acos(-1);
struct A
{
int x=0;//入度
int y=0;//出度
}a[M];
int mapp[M][M];
int main()
{
int n,i,j,ans=0,c,d;
cin>>n;
memset(mapp,0,sizeof(mapp));
for(i=0;i<n-1;i++)
{
cin>>c>>d;
a[c].y++;
a[d].x++;
mapp[c][d]=1;
}
int max1=-1,max2=-1,p=-1,q=-1;
for(i=1;i<=n;i++)
{
if(a[i].y>=max1)
{
max1=a[i].y;
p=i;
}
}
for(i=1;i<=n;i++)
{
if(a[i].y>=max2&&i!=p)
{
max2=a[i].y;
q=i;
}
}
for(i=1;i<=n;i++)
{
if(mapp[p][i]==1)
{
a[i].x--;
}
if(mapp[q][i]==1)
{
a[i].x--;
}
}
for(i=1;i<=n;i++)
{
if(a[i].x==0&&i!=p&&i!=q)
ans++;
}
cout<<ans<<endl;
retu