计蒜之道 AI 伴游小精灵

北京市商汤科技开发有限公司面向青少年研发了一款智能伴游机器人-- 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 也被推倒。

输出格式
输出一个整数表示去掉两个骨牌之后,最坏情况下你最少需要推倒几个骨牌才能使所有骨牌倒下。
样例输入

7
1 2
1 3
1 5
2 4
4 7
4 6

样例输出

5

解题思路:
我的思路是把它画出一颗树,然后找分支最多的结点,删掉,遇到分支一样多的结点,优先找后面的,找两次,然后输出答案,答案就是分支数,即前驱等于自己的结点个数。

#include <bits/stdc++.h>
using namespace std;
int pre[5010];
int cnt[5010];
int main(){
    int n,ans=0;
    cin>>n;
    for(int i=1;i<=n;i++)	pre[i] = i;
    memset(cnt,0,sizeof(cnt));
    int max=0,node=0;
    for(int i=1;i<n;i++){
        int x,y;
        cin>>x>>y;
        pre[y] = x;
        cnt[x]++;
        if(cnt[x]>max||(cnt[x]==max&&x>node)){
            max = cnt[x];
            node = x;
        }
    }
    cnt[pre[node]]--;
    cnt[node]=0;
    pre[node]=0;//去掉Node
    for(int i=node+1;i<=n;i++){
        if(pre[i] == node){
            pre[i] = i;
        }
    }
    int m2=0,d2=0;
    for(int i=1;i<=n;i++){   
            if(cnt[i]>=m2){
                m2 = cnt[i];
                d2 = i;
            }
    }
    for(int i=d2+1;i<=n;i++){
            if(pre[i] == d2){
                pre[i] = i;
            }    
    }
    pre[d2] = 0;
    for(int i=1;i<=n;i++){
        if(pre[i]==i){
            ans++;
        }
    }
    cout<<ans<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Csdn_jey/article/details/90612648