CF F. MST Unification (最小生成树避圈法)
题意
给一个无向加权联通图,没有重边和环。在这个图中可能存在多个最小生成树(MST),你可以进行以下操作:选择某条边使其权值加一,使得MST权值不变且唯一。求最少的操作次数。
分系:首先我们先要知道为什么会出现多个最小生成树的情况? 因为有些边的权值是相同的 , 所以在构造最小生成树的时候 ,我们是可以选择不同的边 , 构造出不同的最小生成树;
如果我们要是生成的最小生成树是唯一的 , 那我们每一次的加边十都只能是一种选择
也就是说,在构造过程的某一次抉择中,如果有多条边,他们的权值均最小,且合法(不会构成环,可以加入MST),而且冲突【二者只能选其一,即选择其中一条后,另一条再加进去就会构成环】,那么我们只选择一条加入MST,剩下的冲突边,都权值加一,那么他们就不能再被选到MST里面了。
为什么必须强调是冲突边?因为如果不冲突,我们可以先选择一条边权最小的(为w)的边e1加入,下次再选择时,边权最小还是为w,但是现在是边e2了,此时e2由于不会构成环,还是可以加入到MST中。所以实际上它们两个是在同一个方案里的,不够成多种选择。
很明显,上面的构造过程是采用了 kruskal算法(即避圈法),我们只需要在构造过程中,统计冲突边的数量,累加起来即可。
---------------------
原文:https://blog.csdn.net/Floraqiu/article/details/86630053
#include<bits/stdc++.h>
using namespace std ;
const int maxn = 2e5+;
int n,m,fa[maxn];
struct no{
int u,v,w;
}e[maxn];
bool cmp(no a , no b)
{
return a.w<b.w;
}
void init(){
for(int i= ; i<=n ; i++)
fa[i]=i;
} int Find(int x)
{
return x==fa[x] ? x:fa[x]=Find(fa[x]);
}
void Merge(int x, int y)
{
int fx = Find(x), fy = Find(y);
if(fx != fy)
fa[x] = fy;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
for(int i= ; i<m ; i++)
scanf("%d%d%d",&e[i].u , &e[i].v , &e[i].w);
sort(e , e+m , cmp);
int ans=;
for(int i= ; i<m ; )
{
int num=;
int j=i;
while(e[i].w ==e[j].w) ///找到权值相同的尾部坐标
j++; for(int k=i ; k<j ; k++) ///i到j都是边权最小而且都是相同的边
{
int fx = Find(e[k].u) , fy=Find(e[k].v);
if(fx!=fy)///统计可以选择的合法边的数量
num++;
}
///注意,我们还得判断合法边里的冲突边 ,才是我们想要的答案
for(int k=i ; k<j ; k++)
{
int fx=Find(e[k].u) , fy=Find(e[k].v);
if(fx!=fy)///从合法边中减去非冲突边(即可以被选入到同一个方案里,不互相冲突的边)
Merge(fx,fy) , num--;
}
i=j;
ans+=num;
}
printf("%d\n",ans);
}
return ;
}
CF F. MST Unification (最小生成树避圈法)的更多相关文章
- (F. MST Unification)最小生成树
题目链接:http://codeforces.com/contest/1108/problem/F 题目大意:给你n个点和m条边,然后让你进行一些操作使得这个图的最小生成树唯一,每次的操作是给某一条边 ...
- CF - 1108 F MST Unification
题目传送门 题意:在一幅图中, 问需要使得多少条边加一,使得最小生成树只有一种方案. 题解:Kruskal, sort完之后,对于相通的一个边权w,我们可以分析出来有多少边是可以被放到图里面的,然后我 ...
- 贪心——Prim算法(避圈法)
1.简介 Prim算法是图论中的一种算法,可在带权连通图里搜索产生最小生成树. 该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(Vojtěch Jarník)发现:并在1957年由美国计算机科学家罗 ...
- Codeforces 1108F MST Unification MST + LCA
Codeforces 1108F MST + LCA F. MST Unification Description: You are given an undirected weighted conn ...
- CF1108F MST Unification
题目地址:CF1108F MST Unification 最小生成树kruskal算法的应用 只需要在算法上改一点点 当扫描到权值为 \(val\) 的边时,我们将所有权值为 \(val\) 的边分为 ...
- 破圈法求解最小生成树c语言实现(已验证)
破圈法求解最小生成树c语言实现(已验证) 下面是算法伪代码,每一个算法都取一个图作为输入,并返回一个边集T. 对该算法,证明T是一棵最小生成树,或者证明T不是一棵最小生成树.此外,对于每个算法,无论它 ...
- Codeforces 1108F MST Unification(最小生成树性质)
题目链接:MST Unification 题意:给定一张连通的无向带权图.存在给边权加一的操作,求最少操作数,使得最小生成树唯一. 题解:最小生成树在算法导论中有这个性质: 把一个连通无向图的生成树边 ...
- uva11549 Floyd判圈法
题意: 给两个数n, k,每次将k平方取k的前n位,问所有出现过的数的最大值 原来这就是floyd判圈法.. #include<cstdio> #include<cstdlib> ...
- 【AtCoder2134】ZigZag MST(最小生成树)
[AtCoder2134]ZigZag MST(最小生成树) 题面 洛谷 AtCoder 题解 这题就很鬼畜.. 既然每次连边,连出来的边的权值是递增的,所以拿个线段树xjb维护一下就可以做了.那么意 ...
随机推荐
- Docker学习笔记_安装和使用mysql
一.系统环境和准备 1.宿主机OS:Win10 64位 2.虚拟机OS:Ubuntu18.04 3.操作账号:docker 二.安装 1.搜索mysql镜像:docker search mysql 2 ...
- 在英文Win7操作系统上部署C#开发的Web系统出现乱码的解决方法
今天,迁移机器,把一个使用C#开发的Web系统部署到一台英文版Win7操作系统上,部署好以后,系统可以登录,只是网页上出现汉字乱码. 在这台电脑上,打开Word等文本编辑器,是可以正常输入.显示中文的 ...
- c语言实践 创建两个包含8个元素的double类型数组,第二个元素的每个元素的值都是对应前一个元素的前n个元素的和
意思就是第二个元素的num[2]等于第一个元素的num[0]+num[1]+num[2] #define COUNT 8 int main(void) { double num1[COUNT]; do ...
- 过渡函数transition-timing-function
- Eclipse操作技巧记录
工欲善其事,必先利其器.记录下自己使用的eclipse操作技巧 1.eclipse设置自动提示 window->preference->java->editor->conten ...
- [.net 多线程]Semaphore信号量
信号量(Semaphore)是一种CLR中的内核同步对象.与标准的排他锁对象(Monitor,Mutex,SpinLock)不同的是,它不是一个排他的锁对象,它与SemaphoreSlim,Reade ...
- mvc 高并发解决方案之一---存储过程
MVC用户访问多线程,一般的lock是无法造成单例的. 存储过程既是一种解决方案,先来看看存储过程优缺点: A. 存储过程允许标准组件式编程 存储过程创建后可以在程序中被多次调用执行,而不必重新编写该 ...
- 使用VS Code编写Markdown文件
VS Code默认支持Markdown文件文件格式,这里介绍两个比较实用的功能,后续有新发现,可以持续更新. 实时预览 顾名思义,实时编辑,实时预览解析效果. 在VS Code扩展中搜索"M ...
- Android学习笔记AutoCompleteTextView的使用
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...
- Promise超时情况
export const ERROR_PROMISE_TIMEOUT = 'ERROR_PROMISE_TIMEOUT'; export default function (promise, time ...