首页 > 其他分享 >最小生成树专项

最小生成树专项

时间:2024-10-08 18:44:22浏览次数:1  
标签:二分 专项 颜色 每个 int Kruskal 最小 生成 行号

contests-link

A

求最短路啊

那显然只需要看端点颜色不同的边即可

那么依次考虑每条边的贡献

一个想法是暴力修改,不过菊花就死了

一个想法是把颜色相同且相连的点缩在一起然后求剩下边的min,现在至少剩下两个连通块

那根据Boruvka知道,这剩下的最优边必然是MST上的边(对于n个点任意划分为若干个集合,不同集合两两之间最小边的最小值一定在MST上

建出Kruskal重构树?一个点造成贡献当且仅当子树内颜色个数不少于2?

也不太好感觉,可以支持加不支持删

暴力的话就是边太多就死了

由于我们求了MST,不妨一个点维护其到父亲的边的可行性,那么可以类比点分树的计算方法,我们每个点维护到儿子的所有边的贡献,这样可以将点权影响的边变为只需要整体改动和单点修改

发现边应当按照颜色分类,所以我们利用 set map<int,multiset<int>> 存下每个点的每个儿子的边按照颜色分类后的边权最值。

这样的话,答案可以对于每个点单独算,而更改一个点的颜色,相当于是更改了那个点的2个set 对答案的贡献状态,可以 \(O(\log n)\) 做,而考虑对父亲的也是单点修改。

B

考虑支配关系

如果有 \(a<b<c\) 其两两 \(\gcd\) 相同,则显然用 \(a-b,a-c\) 即可,也即 \(b-c\) 是无用的

这就被支配了

枚举 \(\gcd\) 即可

有 \(O(n\log n)\) 条边

C

根据差分的知识,原数组全零相当于差分数组全零,那么可以对于每个点求出 \(l,r\),则可以修改 \(l,r+1\) 两个单点(联动修改)

则所有修改的单点连通即可,跑 Kruskal 就 OK 了

D

没啥好说的,线段树分治,每一层扔掉不可能的边和一定能的边即可,其余递归解决,复杂度双 \(\log\)。

不可能的边指:假定子树内将来会用到的所有边边权全是 \(inf\),也不可能用到的边(也就是本节点涉及的边跑 Kruskal,扔掉无法更新的)。

一定能的边指:假设子树内将来会用到的边边权全是 \(-inf\),也会用到的边(也就是先加入所有的将来边,然后再跑Kruskal仍然能够产生贡献的边)

显然,这样处理之后剩下的边只有 \(O(len)\) 条,下传到左右儿子即可。

很经典。

void sol(int x,int l,int r){
    sort(ad[x].begin(),ad[x].end());
    if(l==r){
        ll lst=dsu::top,tmp=res;
        for(auto [u,v,w]:ad[x])res+=dsu::merge(u,v)*w;
        ans[l]=res;res=tmp;dsu::del(lst);return ;
    }
    ll lst=dsu::top,tmp=res,mid=l+r>>1;
    vector<bool>ud(ad[x].size());
    for(auto [u,v,w]:pas[x])dsu::merge(u,v);
    for(int i=0;i<ad[x].size();++i){
        auto [u,v,w]=ad[x][i];
        if(dsu::merge(u,v))ud[i]=1;
    }
    dsu::del(lst);
    for(int i=0;i<ad[x].size();++i){
        if(ud[i]){dsu::merge(ad[x][i].u,ad[x][i].v);res+=ad[x][i].w;continue;}
        if(dsu::merge(ad[x][i].u,ad[x][i].v)){
            ad[lc].push_back(ad[x][i]);
            ad[rc].push_back(ad[x][i]);
        }
    }
    dsu::del(lst);
    for(int i=0;i<ad[x].size();++i)if(ud[i])dsu::merge(ad[x][i].u,ad[x][i].v);
    ad[x].clear();ad[x].shrink_to_fit();pas[x].clear();pas[x].shrink_to_fit();
    sol(lc,l,mid);sol(rc,mid+1,r);
    res=tmp;dsu::del(lst);
}

E

显然对于值相同的两个点连在一起是最优的,所以可以去掉相同值的贡献,也就是每个值只保留一个元素。

然后由于求最大生成树,考虑Kruskal,从大到小枚举边权,能连的一定连。

则假设现在枚举的边权是 \(x\),还剩下 \(a_1\sim a_m\) 满足 \(a_i\& x=x\)。

则必然有 \(\forall i,j,a_i\&a_j=x\),否则已经提前处理。

且由于这个条件,可以推出 \(m\le \log V\),因为鸽巢原理( \(x\) 的零位最多每个位放一个数到极限了)。

所以可以暴力找扫一遍所有数合并即可。

找数这个步骤,可以在做 Kruskal 的同时做高维后缀和。

当然你可以 Boravka,朴素的想法是计算高维后缀和找最优决策,事实上 Trie 处理按位与往往将“1”子树与“0”子树合并在一起作为新的零子树,按位或同理(像线段树合并一样)每个点最多合并 \(\log V\) 次。

那么相当于每个点有颜色,你Trie维护树内不同颜色个数即可。

    for(int i=(1<<d)-1;i>=0;--i){
		if(!a[i]){
			for(int j=0;j<d;++j)if(a[i|(1<<j)]){
				a[i]=a[i|(1<<j)];break;
			}
		}
		if(!a[i])continue;
		for(int j=0;j<d;++j)if(a[i|(1<<j)]&&find(a[i])!=find(a[i|(1<<j)])){
			ans+=i;f[find(a[i])]=find(a[i|(1<<j)]);
		}
	}

F

首先可以给边赋权之后转化为WQS二分板子

另一个巧妙的想法是拿出必须边,也就是假定用所有白边后仍然需要的黑边,用所有黑边后仍然需要的白边。

这样的必经边拿出来后我们就能够保证连通了,接下来贪心先处理白边,在次数充足时贪心能加就加,次数用完了就加黑边即可。

G

将一个值的 \(x,y\) 拿出来,相当于是做变换

在 \(C\) 时,每个值的 \(x\) 已经归位,也就是每个行号已经OK了

那么可以发现得到一个 \(B\) 之后是可以求出 \(C\) 的,因为变换已经固定了。

所以就必须要满足 \(B\) 里每一列的行号不同,且满足后一定可行,否则就没办法重排。

所以我们只需要做 \(A\to B\) 这一步就好了,满足只移动每一行,然后使得每一列元素行号不同。

有点匹配的味道了

我们只关心每个元素的行号,要通过移动每一行是的每一列的元素值互不相同。

如果建立行列二分图,相当于是每一个列到每一行的边都染为不同颜色

而这个操作移动操作相当于是交换了一个行的两条出边。

你考虑依次调整每个颜色

这里显然有对称性,所以你的开始位置不重要

不过这里也可以看作行号相同的两个点不在同一列上

如果说割开看,相当于是把行号相同的 \(m\) 个元素拿出来,考虑一次性归位一种颜色,然后把 \(m\) 列拿出来组成一个二分图匹配,做 \(n\) 轮就行了,而且这玩意是正则图?

这玩意有后效性应该假了。

那么考虑每次求一列的答案

你对行和颜色建立二分图,行i向其包含的颜色 \(j\) 连接 \(c_{i,j}\) 条边表示该行颜色出现次数。

匹配后就可以拿出一列的答案,如果匹配完美

而且匹配完了之后左部右部每个点的度数全部减少 \(1\),且初始度数全部是 \(n\),局面本质不会改变(霍尔定理始终满足(每个点度数相同,又显然有 \(|E(N(S))|\ge |E(S)|\),而 \(\forall S, |E(S)|=k·|S|\),其中 \(k\) 是常数,所以有 \(|N(S)|\ge |S|\),随便拿出一组匹配之后是没有后效性的)),那就完了。

事实上这是正则图。

建立 \(k\) 正则二分图,随意拿出一组完美匹配不会影响局面,只会变为 \(k-1\) 正则二分图

不知道这个说法对不对,反正感觉说出来挺舒服,这个东西好像叫正则二分图 \(k\) 染色

输出方案真恶心。。。

使用网络流可以做到 \(O(m·(n\sqrt {n^2}))=O(mn^2)\)。

H

二分图匹配模板题。

标签:二分,专项,颜色,每个,int,Kruskal,最小,生成,行号
From: https://www.cnblogs.com/spdarkle/p/18452284

相关文章

  • AI虚拟主播生成插件中的关键代码!
    AI虚拟主播,作为新媒体领域的创新力量,正逐渐改变着我们的信息传播方式,它们不仅能够模拟真实主播的言行举止,还能通过智能算法生成个性化、高质量的内容。在这背后,离不开一套强大的生成插件,而这套插件中的关键代码则是其核心所在,今天,我们就来揭开AI虚拟主播生成插件的神秘面纱,分......
  • 最近雷军AI配音火出圈,一键免费生成!保姆级教程分享!
    这两天被雷军这个AI配音刷屏了,在某音,B站上大火!特别是一些游戏解说都用他的AI配音,随便发一个视频播放量是杠杠的!也算是一个热点了,这热点可以蹭一波。那这个AI配音到底是怎么做出来的呢?其实非常简单,互联网就是信息差,谁先掌握了第一手信息,谁就可以吃肉!几天就给大家讲下如何......
  • 最近雷军AI配音火出圈,一键免费生成!保姆级教程分享!
    这两天被雷军这个AI配音刷屏了,在某音,B站上大火!特别是一些游戏解说都用他的AI配音,随便发一个视频播放量是杠杠的!也算是一个热点了,这热点可以蹭一波。那这个AI配音到底是怎么做出来的呢?其实非常简单,互联网就是信息差,谁先掌握了第一手信息,谁就可以吃肉!几天就给大家讲下如何......
  • 最近雷军AI配音火出圈,一键免费生成!保姆级教程分享!
    这两天被雷军这个AI配音刷屏了,在某音,B站上大火!特别是一些游戏解说都用他的AI配音,随便发一个视频播放量是杠杠的!也算是一个热点了,这热点可以蹭一波。那这个AI配音到底是怎么做出来的呢?其实非常简单,互联网就是信息差,谁先掌握了第一手信息,谁就可以吃肉!几天就给大家讲下如何......
  • 用Python实现AI生成音乐:通过Magenta与MIDIUtil开启音乐与AI的创作之旅
    解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界引言随着人工智能(AI)的快速发展,机器学习在诸多领域得到了广泛应用,其中之一便是音乐生成。通过结合AI技术,计算机不仅能够分析和识别音乐,还能够自动创作音乐。无论是简单的旋律生成,还是复杂的音乐作品,都可以通过AI......
  • 通过Python构建自动化股票分析工具:从数据抓取到技术分析与买卖信号生成
    解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界前言股票市场是一个高度复杂和波动的领域,投资者常常需要依赖技术分析和数据驱动的策略来做出买卖决策。借助Python,我们可以轻松自动化这些任务,帮助我们分析股票趋势、判断买卖时机,并生成交易信号。本文将详细介......
  • 部署cogview图片生成模型
       CogView3是一种新颖的文本生成图像系统,采用了接力扩散的方式,将生成高分辨率图像的过程分解为多个阶段。通过接力的超分辨率过程,对低分辨率生成结果添加高斯噪声,并从这些带噪声的图像开始扩散。我们的结果显示,CogView3的表现优于SDXL,获胜率达到77.0%。此外,通过对扩......
  • <免费开题>登录网站验证码的生成与识别系统(django)|全套源码+文章lw+毕业设计+课程设计
    <免费开题>登录网站验证码的生成与识别系统(django)|全套源码+文章lw+毕业设计+课程设计+数据库+ppt摘要近年来随着互联网应用技术的飞速发展,为了确保网站系统平台的安全性,各类网站相继推出了验证码应用技术,通过验证码的应用来帮助缓解暴力破解账户密码、垃圾邮件攻击以及在......
  • Java生成条形码(亲测可通过扫码枪扫出)
    Java生成条形码(亲测可通过扫码枪扫出)秃秃爱健身  该博客介绍了如何在Java项目中通过barcode4j库生成Code128条形码,解决了条形码扫不出或美观度不足的问题。提供了相关代码示例,包括Maven依赖、工具类和生成条形码的方法,可以自定义条形码的高度、宽度、是否留白和隐藏文本。摘......
  • 上海AI Lab视频生成大模型书生.筑梦环境搭建&推理测试
    引子最近视频生成大模型层出不穷,上海AILab推出新一代视频生成大模型“书生・筑梦2.0”(Vchitect2.0)。根据官方介绍,书生・筑梦2.0是集文生视频、图生视频、插帧超分、训练系统一体化的视频生成大模型。OK,那就让我们开始吧。一、模型介绍筑梦2.0支持5s-20s长视频生成......