【OI】Kruskal & ufs (克鲁斯卡与并查集)
Kruskal是有关于最小生成树的算法。
这个算法非常好理解,用一句话来概括就是:
从小到大找不同集合的边。
那么,具体是怎样的呢。
1.先把所有顶点初始化为一个连通分量。
2.从所有边中选择最小的(指权值)边,判断该边是否已经在当前构造的连通分量中,如果是,则放弃这条边,找下一条边。
3.重复第二步,直到所有点都被纳入到当前构造的连通分量中。
所以,这样的算法涉及到了查询当前边是否在集合中和合并一条边到集合中。
于是想到了并查集。
先贴并查集代码,并查集的思想是用一个父亲数组:fa[i]代表节点i的父亲,以此将某节点并为某节点儿子来合并,查询。
#include<iostream>
using namespace std;
int par[],ran[];
void init(int N)
{
for(int k=;k<N;k++)
{
par[k]=k;
}
}
int find(int x)
{
if(par[x]==x)
{
return x;
}
else
{
return find(par[x]);
}
}
void unionn(int x,int y)
{
x=find(x);
y=find(y);
if(ran[x]<ran[y])
{
par[x]=y;
}
else
{
par[y]=x;
if(ran[x]==ran[y])
{
ran[x]++;
}
}
}
bool same(int x,int y)
{
return find(x)==find(y);
}
int main()
{
int n,m,a,b,c;
cin>>n>>m;
init(n+);
for(int i=;i<m;i++)
{
cin>>a>>b>>c;
if(a==)
{
unionn(b,c);
}
else
{
if(same(b,c))
{
cout<<"Y"<<endl;
}
else
{
cout<<"N"<<endl;
}
}
}
return ;
}
并查集代码
然后,我们需要根据这份代码来进行克鲁斯卡算法。
根据之前的思路,可以写出这样的算法:
void kruskal(){
sort(e+1,e+m+1,cmp);
int sum = 0;
int num = 0;
for(int i = 1;i <= m;i++){
int s = e[i].s;
int t = e[i].t;
if(!same(s,t)){
printf("连接%d,%d\n",s,t);
sum += e[i].v;
union_(s,t);
num++;
}
if(num >= n-1) break; }
printf("最小生成树权值和为%d,共有%d个节点",sum,num);
}
看起来似乎很好理解。
这也是一个贪心的思想。
【OI】Kruskal & ufs (克鲁斯卡与并查集)的更多相关文章
- POJ 2421 Constructing Roads (Kruskal算法+压缩路径并查集 )
Constructing Roads Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 19884 Accepted: 83 ...
- 模板——最小生成树kruskal算法+并查集数据结构
并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...
- 【转】并查集&MST题集
转自:http://blog.csdn.net/shahdza/article/details/7779230 [HDU]1213 How Many Tables 基础并查集★1272 小希的迷宫 基 ...
- 算法笔记--可撤销并查集 && 可持久化并查集
可撤销并查集模板: struct UFS { stack<pair<int*, int>> stk; int fa[N], rnk[N]; inline void init(i ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- 洛谷P1991无线通讯网[kruskal | 二分答案 并查集]
题目描述 国防部计划用无线网络连接若干个边防哨所.2 种不同的通讯技术用来搭建无线网络: 每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫星电话线路的哨所(两边都 ...
- hdu 3938 Portal(并查集+离线+kruskal)2011 Multi-University Training Contest 10
搜了题解才把题搞明白.明白之后发现其实题意很清晰,解题思路也很清晰,只是题目表述的很不清晰…… 大意如下—— 给你一个无向图,图中任意两点的距离是两点间所有路径上的某一条边,这条边需要满足两个条件:1 ...
- 稀疏图(邻接链表),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)
全部函数通过杭电 1142,1162,1198,1213等题目测试. #include<iostream> #include<vector> #include<queue ...
- 稠密图(邻接矩阵),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)
全部函数通过杭电 1142,1162,1198,1213等题目测试. #include<iostream> #include<vector> #include<queue ...
随机推荐
- 用SQLyog或Navicat远程连接数据库
以SQLyog为例(Navicat同理): 登录远程数据库服务器查看当前存在用户:即点击用户管理器(人像图标),查看用户. 1)如果某一用户 主机一栏中是"%",则表示本用户是开放 ...
- 简单说一下Set,list,Map的类型和自己的特点
首先是Set,List,Map Set和list都是继承了Conllection接口,而Map是本身就是一个接口 set是最简单的一种集合,没有重复对象 set接口主要有两个实现: 1,hashSet ...
- MySQL和Oracle的比较
可以从以下几个方面来进行比较: (1) 对事务的提交 MySQL默认是自动提交,而Oracle默认不自动提交,需要用户手动提交,需要在写commit;指令或者点击commit按钮(2) 分页查询 ...
- C++ string 转整数
使用 sstream 完成转换, #include <iostream> #include <string> #include <sstream> #include ...
- Android : reletive layout
在兄弟的上下左右: android:layout_toRightOf="@id/btn1"/> android:layout_toLeftOf="@id/img1& ...
- 获取某一个<tr>中<td>的值
$("#trId").children("td").eq(0).text(}; //当前行的第一个<td>的值 <td>下标 ...
- Happy Three Friends
Happy Three Friends Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- Android BGABadgeView:BGABadgeImageView以及BGABadgeRelativeLayout(4)
Android BGABadgeView:BGABadgeImageView以及BGABadgeRelativeLayout(4) 在附录文章5,6,7的基础上,写一个小例子说明BGABadge ...
- [SCOI2008]奖励关 - 状压动规 - 概率与期望
Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝 ...
- Codeforces704B. Ant Man
n<=5000个数轴上的点,有属性x,a,b,c,d,从i跳到j的代价如下: 问从s跳到t的最小代价. 方法?:先构造s->t链,然后依次插入其他点,每次选个最佳的位置.过了这题,正确性不 ...