【 Codeforces Round #518 (Div. 2) [Thanks, Mail.Ru!] E. Multihedgehog】 set+vector滚动数组

本文介绍了一种用于判断特定类型树结构——刺猬树的算法。刺猬树是一种特殊的树形结构,其定义依赖于树的层数和节点度数。文章详细阐述了算法的实现步骤,包括初始化树的结构,计算最小节点数,通过递归去除度数为1的节点,直至判断树是否符合刺猬树的定义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


E. Multihedgehog

题意

给你一颗n个节点的树,让你判断是不是刺猬数给你一颗n个节点的树,让你判断是不是刺猬数n
1层刺猬树的定义为, 有一个节点度数>=3 其余节点度数为11层刺猬树的定义为,\ 有一个节点度数>=3 \ 其余节点度数为11 >=3 1
k层刺猬树的定义为,有一个节点的度数>=3 其余节点为一颗k−1层树的根k层刺猬树的定义为,有一个节点的度数>=3 \ 其余节点为一颗k-1层树的根k>=3 k1

1&lt;=n&lt;=105,1&lt;=k&lt;=1091&lt;=n&lt;=10^5,1&lt;=k&lt;=10^91<=n<=105,1<=k<=109
做法
首先一颗k层刺猬树有最少节点数首先一颗k层刺猬树有最少节点数k
所以先判断一下n是否大于等于k层刺猬树所需节点数所以先判断一下n是否大于等于k层刺猬树所需节点数nk
之后重复这样一个过程,每次找出度数为1的点,把与他们相连的点丢尽vector,之后重复这样一个过程,每次找出度数为1的点,把与他们相连的点丢尽vector,1vector,
并在与他们相连的点的set种删除本点并在与他们相连的点的set种删除本点set
丢进vector的点sum++丢进vector的点sum++vectorsum++
如果他们满足每个点的sum&gt;=3,就重复这个过程如果他们满足每个点的sum&gt;=3,就重复这个过程sum>=3
最后看k层之后是否只剩下一个点,而且这个点的度数&gt;=3最后看k层之后是否只剩下一个点,而且这个点的度数&gt;=3k>=3

代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<set>
using namespace std;
typedef long long ll;
#define dbg(x) cout<<#x<<" = "<<x<<endl;
const int maxn = 1e5+10;
map<int,int> mp1,mp2;
set<int> s[maxn];
int sum[maxn];//记录每个点有多少个儿子
int vis[maxn];
vector<int> tmp[2];//存每次前驱的id
int main()
{
    int n,k,u,v;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d%d",&u,&v);
        s[u].insert(v);
        s[v].insert(u);
    }
    ll tm=1;
    for(int i=1;i<=k;i++)
    {
        tm=tm*3LL;
        if(tm>(2*n+1))
        {
            printf("No\n");
            return 0;
        }
    }
    int flag=0;
    for(int i=1;i<=n;i++)
    {
        if(s[i].size()==1)
        {
            sum[i]=3;
            tmp[1].push_back(i);
        }
    }
    for(int i=1;i<=k;i++)
    {
        tmp[(i+1)%2].clear();//vector是滚动的,用两个vector达到目的
        for(int j=0;j<tmp[i%2].size();j++)
        {
            if(sum[tmp[i%2][j]]<3||s[tmp[i%2][j]].size()!=1)
            //如果有一个点不满足sum大于3
            //或者这个点还存在超过两个边
            {
                flag=1;
                break;
            }
            else
            {
                int tt=*s[tmp[i%2][j]].begin();
                int tt2=tmp[i%2][j];
                s[tt].erase(tt2);//在相连的点的边种删除本条边
                sum[tt]++;
                if(vis[tt]) continue;
                else
                {
                    tmp[(i+1)%2].push_back(tt);
                    vis[tt]=1;
                }
            }
        }
        if(flag==1) break;
    }
    if(flag==0&&tmp[(k+1)%2].size()==1&&sum[tmp[(k+1)%2][0]]>=3&&s[tmp[(k+1)%2][0]].size()==0) printf("Yes\n");
    //flag=0 表示满足刺猬树属性
    //tmp[(k+1)%2].size()==1表示最后的点为根
    //sum[tmp[(k+1)%2][0]]>=3 表示根节点满足度数>=3
    //s[tmp[(k+1)%2][0]].size()==0表示最后根节点不再有其他儿子
    else printf("No\n");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值