• [CF1491E] Fib-tree


    [CF1491E] Fib-tree - 分治,树

    Description

    现在给你一棵包含了 (n) 个结点的树。我们称一棵树为 Fib-tree,要求其结点树为某一个 (F_k),且满足以下至少一个:树仅包含一个结点;从某条边划开,形成的两棵子树都是 Fib-tree。请判断给出的树是不是 Fib-tree。

    Solution

    如果是个 Fib-tree,那么一定可以切成一个 n-1-Fib-tree 和一个 n-2-Fib-tree

    有时候可以有多种切法,但是可以归纳证明,只要是 Fib-tree,无论哪一种切法都是可行的

    假设有两条边 e1,e2,都是可行的,我们切 e1,那么 e2 一定在那个 n-1-Fib-tree 内,可以参与下一次切割

    因此,能切就切,分治求解

    #include <bits/stdc++.h>
    using namespace std;
     
    const int N = 1000005;
     
    set<int> g[N];
    int n;
    int siz[N];
    int fib[N],fid[N],fa[N];
    vector<int> vec;
     
    void dfs(int p,int from)
    {
        siz[p]=1;
        vec.push_back(p);
        for(int q:g[p]) if(q!=from)
        {
            dfs(q,p);
            fa[q]=p;
            siz[p]+=siz[q];
        }
    }
     
    bool check(int p,int size)
    {
        if(size<=3) return true;
        vec.clear();
        dfs(p,0);
        int size_id=fid[size];
        int tar_size=fib[size_id-1];
        int res_p=0,res_q=0,psize=0;
        for(int i:vec)
        {
            if(siz[i]==tar_size || size-siz[i]==tar_size)
            {
                res_p=i;
                res_q=fa[i];
                psize=siz[p];
                break;
            }
        }
        if(res_p)
        {
            g[res_p].erase(res_q);
            g[res_q].erase(res_p);
            return check(res_p,psize) && check(res_q,size-psize);
        }
        else 
        {
            return false;
        }
    }
     
    signed main()
    {
        ios::sync_with_stdio(false);
        int n;
        cin >> n;
        fib[0]=fib[1]=1;
        for(int i=2;i<=30;i++) fib[i]=fib[i-1]+fib[i-2];
        for(int i=1;i<=30;i++) fid[fib[i]]=i;
        for (int i = 1; i < n; i++)
        {
            int t1, t2;
            cin >> t1 >> t2;
            g[t1].insert(t2);
            g[t2].insert(t1);
        }
        if (check(1,n))
        {
            cout << "YES" << endl;
        }
        else
        {
            cout << "NO" << endl;
        }
    }
    
  • 相关阅读:
    ElasticSearch基本用法
    几款Http小服务器
    【最长上升子序列】HDU 1087——Super Jumping! Jumping! Jumping!
    方差与样本方差、协方差与样本协方差
    方差与样本方差、协方差与样本协方差
    统计推断(statistical inference)
    统计推断(statistical inference)
    R 语言学习(二)—— 向量
    R 语言学习(二)—— 向量
    R 语言的学习(一)
  • 原文地址:https://www.cnblogs.com/mollnn/p/14473024.html
Copyright © 2020-2023  润新知