首页 > 其他分享 >【内向基环树】LeetCode 2127. 参加会议的最多员工数

【内向基环树】LeetCode 2127. 参加会议的最多员工数

时间:2024-12-22 14:09:44浏览次数:8  
标签:fr 环上 2127 int favorite mx 基环树 ans LeetCode

题目

https://leetcode.cn/problems/maximum-employees-to-be-invited-to-a-meeting/description/

题解

从 \(i\) 向 \(favorite[i]\) 连边,会形成一张 \(n\) 个点 \(n\) 条边的有向图,且该图包含若干个连通块,每个连通块均为基环树,亦即该有向图为基环树森林

以测试用例[1, 2, 0],进行分析:

假设从中选择任意的点,例如:

此时显然没有全部人喜欢的人都参加会议,由于 \(1\) 喜欢的人未参加,故而该选法必定不会满足。那么什么情况可以满足每个人喜欢的人都有参加呢?
答:存在一个环的时候,可以使得每个人喜欢的人都有参加。

由于参加会议是坐在圆桌上,因此隐含了一个条件:每个人周围至多可以坐两个不同的人,但其中一个必须是喜欢之人。

若参加会议的人,全部位于环上,明显全部可以参加。
若参加会议的人,不止环上的人,则需要进行以下分类讨论:

  1. 环上人数大于 \(2\):环上的每个人,两侧必定是一个为自己喜欢之人,一个为喜欢自己之人,因此周围两个人都是确定的,若还有位于环外的人喜欢自身,会造成坐在自身旁边的人数超过 \(2\),会破坏周围只能做两个不同的人的条件。因此,该种情况环的大小就是答案;
  2. 环上人数等于 \(2\):环上的人,坐在一起后,周围均可以再坐一个喜欢自己之人。因此,该种情况就是环的大小加两个不同节点的最大外链长度。且该种情况,可以多个环进行累计,因为每个环的外链末端都可以再坐一个人。

参考代码

class Solution {
public:
    int maximumInvitations(vector<int>& favorite) {
        int ans = 0, n = favorite.size(), cnt = 0;
        vector<int> in(n), mx(n), v;
        for (int &f: favorite) ++ in[f];
        for (int i = 0; i < n; ++ i) if (!in[i]) v.emplace_back(i);
        for (int fr = 0, rr = v.size(); fr < rr; rr = v.size()) {
            while (fr < rr) {
                int &cur = v[fr], &nxt = favorite[v[fr]];
                mx[nxt] = max(mx[nxt], mx[cur] + 1);
                if (-- in[nxt] == 0) v.emplace_back(nxt);
                ++ fr;
            }
        }
        for (int i = 0; i < n; ++ i) {
            if (in[i]) {
                int res = 0, m1 = 0, m2 = 0;
                for (int j = i; in[j] > 0; j = favorite[j]) {
                    -- in[j]; 
                    if (m1 < mx[j]) m2 = m1, m1 = mx[j];
                    else if (m2 < mx[j]) m2 = mx[j];
                    ++ res;
                }
                if (res == 2) cnt += res + m1 + m2;
                else ans = max(ans, res);
            }
        }
        ans = max(ans, cnt);
        return ans;
    }
};

标签:fr,环上,2127,int,favorite,mx,基环树,ans,LeetCode
From: https://www.cnblogs.com/RomanLin/p/18618538

相关文章

  • 1596. 每位顾客最经常订购的商品 - 力扣(LeetCode)
    1596.每位顾客最经常订购的商品-力扣(LeetCode)目标输入表:Productsproduct_idproduct_nameprice1keyboard1202mouse803screen6004harddisk450表:Ordersorder_idorder_datecustomer_idproduct_id12020/7/311122020/7/302232020/8/293342020/7/294152020/6/101262020/8/1......
  • LeetCode72. 编辑距离(2024冬季每日一题 37)
    给你两个单词word1和word2,请返回将word1转换成word2所使用的最少操作数。你可以对一个单词进行如下三种操作:插入一个字符删除一个字符替换一个字符示例1:输入:word1=“horse”,word2=“ros”输出:3解释:horse->rorse(将‘h’替换为‘r’)rorse->......
  • LeetCode 热题 第17题 电话号码的字母组合
    LeetCode热题17电话号码的字母组合给定一个仅包含数字2-9的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。给出数字到字母的映射如下(与电话按键相同)。注意1不对应任何字母。解答classSolution{public:vector<string>letterCombinations......
  • LeetCode - #166 分数到小数
    文章目录前言1.描述2.示例3.答案关于我们前言我们社区陆续会将顾毅(Netflix增长黑客,《iOS面试之道》作者,ACE职业健身教练。)的Swift算法题题解整理为文字版以方便大家学习与阅读。LeetCode算法到目前我们已经更新到163期,我们会保持更新时间和进度(周一、......
  • 12.16 二叉树的题目用acm模式 leetcode
    任务有leetcode1.将所有二叉树的题目用acm模式进行补充(完成了)github上面的所有二叉树ACM答案,模板https://github.com/PUNKDONG/leetcode/tree/master/src/treenodepackagetreenode;importjava.util.*;publicclasstreecode0_template{staticclassTreeNo......
  • leetcode 2592. 最大化数组的伟大值
    2592.最大化数组的伟大值法一:排序丑陋的代码classSolution{public:intmaximizeGreatness(vector<int>&nums){sort(nums.begin(),nums.end());intsize=nums.size(),res=0;for(inti=0,j=0;i<size&&j<size;+......
  • leetcode 8. 字符串转换整数 (atoi)
    8.字符串转换整数(atoi)丑陋的代码classSolution{public:intmyAtoi(strings){inti=0,size=s.size();boolisPositive=true;longres=0;while(s[i]=='')++i;//跳过空格if(s[i]=='-'){......
  • LeetCode 热题 第35题 搜索插入位置
    LeetCode热题第35题搜索插入位置给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为O(logn)的算法。解题:classSolution{public:intsearchInsert(vector<int>&......
  • LeetCode题集-9 - 回文数
    题目:给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。01、反转字符串法此题我第一反应就是直接把整数转为字符串,然后通过字符串Reverse方法,反转字符串,最后......
  • LeetCode-19. 删除链表的倒数第 N 个结点,关于删除链表会遇见的指针问题
    原题链接前言虽然这道题比较简单,但是我在做这道题时发现了几个需要注意的地方,故写个笔记提一下。正文先将源代码给出来classSolution{public:ListNode*removeNthFromEnd(ListNode*head,intn){ListNode*x=newListNode();x->next=head......