基环树,基环内向树,基环外向树

基环树

如果图G是连通的,并且无回路,则称G为树。我们给树任意加一条边,就出现了环,我们称之为
基环树(pseudotree)。

上面都是无向树,如果变为有向树,则可进一步分为基环内向树和基环外向树。

基环内向树

如果一个有向基环树满足每个节点出度为1,那么我们称之为基环内向树

 特性

每棵基环内向树只有一个基环和若干树枝。(反证法去证和出度为1矛盾)

OJ链接

2127. 参加会议的最多员工数

内向基环树 拓扑+分类讨论

首先基环内向树只有一个基环和若干树枝

对于长度大于2的基环来讲,它们可以坐一桌,树枝插不进来

1.png

对于长度等于2的基环来讲,它们俩可以坐一起同时可以各自带一条树枝链,最长情况就是各自带最长的树枝链

3.png

因此我们可以通过拓扑排序剪掉树枝,拓扑后还剩若干基环(因为有可能是基环树森林,所以基环可能不唯一) 遍历得最大环长度

因为基环长度可能为2,那么我们还要维护一个最长树枝链条长度,对于每个节点的最长链条长度我们可以在拓扑的时候dp维护

代码如下

class Solution {
public:
    int maximumInvitations(vector<int>& favorite) {
        //建图   拓扑剪掉述职  建立反图
        //拓扑后还剩若干环   遍历得最大环长度
        int n = favorite.size();
        vector<int> in(n);
        for(auto x :  favorite)
        in[x]++;
        queue<int> q;
        vector<int> depth(n , 1);
        for(int i = 0 ; i < n ; i++)
        if(!in[i])
        q.push(i);
        while(!q.empty())
        {
            int f = q.front();q.pop();
            if(!(--in[favorite[f]]))
            q.push(favorite[f]);
            depth[favorite[f]] = depth[f] + 1;
        }
        int max_ring = 0 , max_link = 0l;
        for(int i = 0 ; i < n ; i++)
        {
            if(!in[i])
            continue;
            int r = 1 , f = favorite[i];
            while(f != i)
            {
                in[f] = 0;
                f = favorite[f];r++;
            }
            in[i] = 0;
            if(r == 2)
            {
                max_link += depth[i] + depth[favorite[i]] ;
            }
            else
            {
                max_ring = max(max_ring , r);
            }
        }
        return max(max_link , max_ring);
        
    }
};

基环外向树

如果一个有向基环树满足每个节点入度为1,那么我们称之为基环外向树

 特性

每棵基环外向树只有一个基环和若干树枝。(反证法去证和入度为1矛盾)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EQUINOX1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值