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维护一下就可以做了.那么意 ...
随机推荐
- SQL SERVER FOR XML PATH合并字符串
两种方式,效率立竿见影 ------------------------------------------------ SET STATISTICS TIME ON DECLARE @OrderSt ...
- GNU 和 g++(转)
百度知道 GNU计划,又称革奴计划,是由Richard Stallman在1983年9月27日公开发起的.它的目标是创建一套完全自由的操作系统.Richard Stallman最早是在net.unix ...
- HDU 5293 Tree chain problem
树状数组 + dp 设$f_i$表示以$i$为根的子树中的能选取的最大和,$sum_x$表示$\sum_{f_y}$ ($y$是$x$的一个儿子),这样子我们把所有给出的链按照两点的$lca$分组, ...
- ls -al
ls -al:显示当前文件下所有的文件
- c++(重载等号=操作为深拷贝)
// ConsoleApplication19.cpp : 定义控制台应用程序的入口点. // #pragma warning(disable:4996) #include "stdafx. ...
- App测试从入门到精通之功能测试
App的功能测试指的是针对软件需求以及用户要求针对APP功能进行测试.简单点理解就是保证App功能的正确性,不要系统出现Bug.让用户用户的舒服,用的爽!好了,我们看下关于App的功能测试要点有哪些? ...
- javascript总结7:算术运算符
1 运算符: 加号+ 如果是数字类型的变量相加,那么结果为数字类型; 如果是非数字类型的变量相加,结果为字符串类型 2 减号- 如果是非数字类型的变量相减结果为 NaN 3 乘号 * 如果是非数 ...
- 手动给kvm虚机挂载lvm卷
1.查看计算节点上虚机挂载的卷 [root@xgto01n010243186070 ~]# virsh domblklist instance- Target Source ------------- ...
- C# LINQ(2)
前一章的代码LINQ都是以select结尾. 之前也说过可以group结尾. 那么怎么使用呢? 还是一样的条件,查询小于5大于0的元素 代码: ,,,,,,,,, }; var list = from ...
- linux联网配置(更新)
重启网络配置:service network restart: 常见问题: linux 虚拟机ifconfig 显示eth1 文件ifcfg-eth0中device为eth0的问题 为什么eth0 ...