首页 > 其他分享 >AcWing 第 92 场周赛 C题 4866. 最大数量 题解

AcWing 第 92 场周赛 C题 4866. 最大数量 题解

时间:2023-02-25 21:12:52浏览次数:57  
标签:周赛 int 题解 菊花 链表 fa behind num 92

原题链接

链表 + 并查集乱搞做法:

思路

首先可以发现,想要让度数尽量大,那我们应该构造成菊花图,即下图所示:

对于每个需求,我们可以知道,如果之前他们没有连在一起,那我们一定得把他们连在一起,该过程使用并查集维护。

如果他们已经连接了,实际上我们就多出来一条“自由边”。

对于自由边,如何进行利用呢,肯定是将包含点数最多的几个菊花团连在一起,重新组合形成一个大的菊花最好。

于是有了以下做法:

对于每个询问,如果两点之间不在同一菊花内,直接进行连接,同时把其中一点从链表中删去,这表示该点不为菊花的中心。

如果两点已经在同一菊花内了,将自由边数\(num\)加一,同时将链表内节点以儿子数进行排序,并将前\(num + 1\)个累加作为答案输出(加一是因为 num 是合并的次数,合并 num 次实际上应该有 num + 1团菊花)

代码

#include <bits/stdc++.h>
#define MAXn 1010
using namespace std;

int n, d;

int fa[MAXn], deep[MAXn], num;

int paixu[MAXn], cnt;//重排序数组

struct point
{
    int front, behind;
}p[MAXn];//链表节点


inline int getfa(int x)//并查集
{
    if(x == fa[x])
        return fa[x];
    return fa[x] = getfa(fa[x]);
}

bool com(int a, int b){ return a > b;}//从大到小排序

int main()
{
    cin >> n >> d;
    for(int i = 1; i <= n; i++)
    {
        p[i].front = i - 1;
        p[i].behind = i + 1;
        fa[i] = i;
        deep[i] = 1;
    }
    p[0].behind = 1;
    p[n + 1].front = n;//初始化
    
    while(d--)
    {
        int x, y;
        cin >> x >> y;
        int fa_x = getfa(x), fa_y = getfa(y);
        if(fa_x != fa_y)//不在联通块内
        {
            fa[fa_y] = fa_x;
            deep[fa_x] += deep[fa_y];//合并,注意看清不用上面并给x,下面加给y了
            p[p[fa_y].front].behind = p[fa_y].behind;
            p[p[fa_y].behind].front = p[fa_y].front;//从链表中删除
        }
        else num++;//在,自由边加1
        int i = p[0].behind;//开始遍历链表
        cnt = 0;
        while(i <= n)
        {
            paixu[++cnt] = deep[i];
            i = p[i].behind;
        }
        sort(paixu + 1, paixu + cnt + 1, com);//排序
        int ans = paixu[1];
        for(int i = 2; i <= num + 1; i++)
        {
            ans += paixu[i];
        }//利用自由边
        
        cout << ans - 1 << "\n";//减一是因为,我们统计时是用的连通块大小,但是题目问的是度的大小
    }
    
    return 0;
}

标签:周赛,int,题解,菊花,链表,fa,behind,num,92
From: https://www.cnblogs.com/six-one/p/17155376.html

相关文章

  • [WC/CTS2023] 楼梯 题解
    题目链接简要题意有一块楼梯,这里指的楼梯是倒着的,正过来看上一层宽度一定小于等于这一层宽度,并且由格子组成,你需要对其进行增删和恢复某一历史版本的操作,并回答这块楼梯......
  • 适用于初学者的CF1654E Arithmetic Operations题解
    题目让我们求改变数字的最少次数,那我们转化一下,求可以保留最多的数字个数\(cnt\),再用\(n\)减一下就行,即\(res=n-cnt\)。我们先考虑两种暴力方法。第一种暴力方......
  • CF717A Festival Organization 题解
    传送门首先考虑求出长度为\(i\)的合法串的个数。很明显可以想到用dp解。设\(f_{i,0/1}\)为长度为\(i\)最后一位为\(0/1\)的合法串个数。可以很容易想到转移......
  • ABC267D 题解
    前言题目传送门!更好的阅读体验?两篇题解的代码写得很复杂,我是没有想到。思路很显然对于一个点,它必定会进入一个循环节。如何判断它进入循环节了呢?当一个点被经过两次,......
  • CF1383E 题解
    题意传送门给定一个长度为\(n\)的01串\(a\)。在一次操作中,你可以选择任意一个\(i\in[1,|a|)\),令\(a_i=\max(a_i,a_{i+1})\),然后将\(a_{i+1}\)删除。你可以进行......
  • AtCoder Beginner Contest 287 A-F 题解
    比赛链接A-Majority先这样再那样最后这样,就是这样。点击查看代码#include<cstdio>#include<algorithm>#include<cstring>usingnamespacestd;intn,a;char......
  • AtCoder Beginner Contest 286 A-G 题解
    比赛链接A-RangeSwap根据题意,分段输出。点击查看代码#include<cstdio>#include<algorithm>#include<cstring>usingnamespacestd;constintN=105;intn,......
  • P8720 [蓝桥杯 2020 省 B2] 平面切分 题解
    前言建议本题评黄,因为需要较强的数学能力。如果格式炸了去这里看哦题意给出\(N\)条直线的解析式\(y=kx+b\),求出这些直线把平面分成了几部分。思路看到这道题我们......
  • 892~893 maven概述,依赖管理的概念
    Maven:1.1、概述:Maven是一个项目管理工具,它包含了一个项目对象模型(POM:ProjectObjectModel),一组标准集合,一个项目生命周期(ProjectLifecycle),......
  • [六省联考 2017] 组合数问题 题解
    题目描述组合数\(C_n^m\)表示的是从\(n\)个互不相同的物品中选出\(m\)个物品的方案数。举个例子,从\((1,2,3)\)三个物品中选择两个物品可以有\((1,2)\),\((1,......