Kuskual算法

流程

  • 1 将图G看做一个森林,每个顶点为一棵独立的树
  • 2 将所有的边加入集合S,即一开始S = E( 并查集)
  • 3 从S中拿出一条最短的边(u,v),如果(u,v)不在同一棵树内,则连接u,v合并这两棵树,同时将(u,v)加入生成树的边集E'
  • 重复(3)直到所有点属于同一棵树,边集E'就是一棵最小生成树

P55-图-6.Kruskal算法_哔哩哔哩_bilibili

typedef struct
{
int a,b;
int w;
}Road;
Road road[maxSize];
//并查集 获取根节点
int getRoot(int i)
{
if(fa[i]==i) return i; //递归出口,当到达了祖先位置,就返回祖先
else
{
fa[i]=getRoot(fa[i]); //路径压缩
return fa[i]; //不断向上查找祖先
}
}
//n是节点个数 m是边数
void Kruskal(Road road[],int n,int m,int &sum)
{
int a,b;
sum=0;
for(int i=0;i<n;i++)
v[i]=i;
sort(road,m);
for(int i=0;i<n;i++)
{
a=getRoot(road[i].a);
b=getRoot(road[i].b);
if(a!=b)
{
v[a]=b;
sum+=road[i].w;
}
}
}

例题

P1194 买礼物 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

输入 #2

3 3
0 2 4
2 0 2
4 2 0

输出

7

说明/提示

样例解释 2。

先买第 2 样东西,花费 3 元,接下来因为优惠,买 1,3 样都只要 2 元,共 7 元。

(同时满足多个“优惠”的时候,聪明的明明当然不会选择用 4 元买剩下那件,而选择用 2 元。)

数据说明:1<=B<=500 A>=0 Ki j<=1000

#include <stdio.h>
#define MaxN 501 typedef struct {
int need;
int from, to;
} node; int father[ MaxN ];
node mp[ 250001 ]; //点数的最大值是500 故可能有500*499条边 void Sort( int left, int right ) {
if ( left > right ) {
return;
}
int i, j;
node k;
i = left, j = right;
k = mp[ left ];
while ( i != j ) {
while ( k.need >= mp[ j ].need && i != j ) {
j --;
}
if ( i != j ) {
mp[ i ++ ] = mp[ j ];
}
while ( k.need <= mp[ i ].need && i != j ) {
i ++;
}
if ( i != j ) {
mp[ j -- ] = mp[ i ];
}
}
mp[ i ] = k;
Sort( left, i - 1 );
Sort( i + 1, right );
return;
} int Find( int i) {
if(father[i]==i) return i; //递归出口,当到达了祖先位置,就返回祖先
else
{
father[i]=Find(father[i]); //路径压缩
return father[i]; //不断向上查找祖先
}
} int main( ) {
int i, j, k;
int A, B;
int posi = 1;
int ans = 0, cnt = 1;
scanf("%d %d", &A, &B );
for ( i = 1; i <= B; i ++ ) {
father[ i ] = i;
}
//设置节点结构体数组
for ( i = 1; i <= B; i ++ ) {
for ( j = 1; j <= B; j ++ ) {
scanf("%d", &k );
//只设置邻接矩阵左下角的边即可
if ( i > j ) {
mp[ posi ].from = i;
mp[ posi ].to = j;
if ( k ) {
k = A - k; // 如果k 不为零,那么就把k的数值变为A-k
}
mp[ posi ++ ].need = k;
}
}
}
//开始Kruskal算法
Sort( 1, posi - 1 );
for ( i = 1; cnt < B ; i ++ ) {
if ( Find( mp[ i ].from ) != Find( mp[ i ].to ) ) {
if ( mp[ i ].need < 0 ) {
mp[ i ].need = 0;
}
father[ father[ mp[ i ].to ] ] = father[ mp[ i ].from ];
ans += mp[ i ].need;
cnt ++;
}
}
ans = B * A - ans;
printf("%d\n", ans );
return 0;
}

【ACM程序设计】求最小生成树 Kuskual算法的更多相关文章

  1. 【ACM程序设计】最小生成树 Prim算法

    最小生成树 ● 最小生成树的定义是给定一个无向图,如果它任意两个顶点都联通并且是一棵树,那么我们就称之为生成树(Spanning Tree).如果是带权值的无向图,那么权值之和最小的生成树,我们就称之 ...

  2. SWUST OJ 1075 求最小生成树(Prim算法)

    求最小生成树(Prim算法) 我对提示代码做了简要分析,提示代码大致写了以下几个内容 给了几个基础的工具,邻接表记录图的一个的结构体,记录Prim算法中最近的边的结构体,记录目标边的结构体(始末点,值 ...

  3. 求最小生成树(Prim算法)(1075)

    Description 求出给定无向带权图的最小生成树.图的定点为字符型,权值为不超过100的整形.在提示中已经给出了部分代码,你只需要完善Prim算法即可. Input 第一行为图的顶点个数n    ...

  4. 求最小生成树——Kruskal算法

    给定一个带权值的无向图,要求权值之和最小的生成树,常用的算法有Kruskal算法和Prim算法.这篇文章先介绍Kruskal算法. Kruskal算法的基本思想:先将所有边按权值从小到大排序,然后按顺 ...

  5. Emergency(山东省第一届ACM程序设计真题+Floyd算法变型)

    题目描述 Kudo’s real name is not Kudo. Her name is Kudryavka Anatolyevna Strugatskia, and Kudo is only h ...

  6. prime算法求最小生成树(畅通工程再续)

    连着做了四道畅通工程的题,其实都是一个套路,转化为可以求最小生成树的形式求最小生成树即可 这道题需要注意: 1:因为满足路的长度在10到1000之间才能建路,所以不满足条件的路径长度可以初始化为无穷 ...

  7. 利用Kruskal算法求最小生成树解决聪明的猴子问题 -- 数据结构

    题目:聪明的猴子 链接:https://ac.nowcoder.com/acm/problem/19964 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个 ...

  8. HDU-1233 还是畅通工程 (prim 算法求最小生成树)

    prim 算法求最小生成树 还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  9. Kruskal和Prim算法求最小生成树

    Kruskal算法求最小生成树 测试数据: 5 6 0 1 5 0 2 3 1 2 4 2 4 2 2 3 1 1 4 1 输出: 2 3 1 1 4 1 2 4 2 0 2 3 思路:在保证不产生回 ...

随机推荐

  1. 实验:zk master宕机后,临时节点在新的master上是否存在,结果出人意料

    一.实验 实验说明:3台zk集群,主要验证:master上的客户端,在master上建立临时节点,当master宕机时,其他follower选为主后,临时节点是否存在. 主要是通过此来验证,基于zk的 ...

  2. Thread 类中的 yield 方法有什么作用?

    使当前线程从执行状态(运行状态)变为可执行态(就绪状态). 当前线程到了就绪状态,那么接下来哪个线程会从就绪状态变成执行状态呢?可 能是当前线程,也可能是其他线程,看系统的分配了.

  3. SpringMvc怎么和AJAX相互调用的?

    通过Jackson框架就可以把Java里面的对象直接转化成Js可以识别的Json对象.具体步骤如下 : (1)加入Jackson.jar (2)在配置文件中配置json的映射 (3)在接受Ajax方法 ...

  4. 说说do...while和while的区别

    一.do-while语句 do-while语句的语法: do{ statement }while(expression); 看下面示例: var i=10: do{ i+=2: }while(i< ...

  5. request表示HttpServletRequest对象?

    request表示HttpServletRequest对象.它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, header, 和session数据的有用的方法. response表示 ...

  6. int 和 Integer 哪个会占用更多的内存?

    Integer 对象会占用更多的内存.Integer 是一个对象,需要存储对象的元数据. 但是 int 是一个原始类型的数据,所以占用的空间更少.

  7. read,readline,readlines的特点与区别

    1.read 读取全部文件 with open("test.text", "r",encoding='utf8') as f: print(f.read()) ...

  8. 学习Kvm(一)

     背景介绍 传统数据中心面临的问题: 资源使用率低 资源分配不均 自动化能力差 初始化成本高   云计算: 云计算是一种按使用量付费的模式,这种模式提供可用的.便捷的.按需的网络访问, 进入可配置的计 ...

  9. 如何正确的阅读Datasheet?

    不仅仅是芯片,包括工具.设备几乎任何电子产品,都需要去阅读它的datasheet,除了包括最低.最高要求,特点,建议和用途及其兼容的设备等等,更重要的是原厂商以一个成功者的身份去告诉你一些注意事项. ...

  10. 如何形成一个完整的HTML对象

    写在前面,本文将同步发布于Blog.掘金.segmentfault.知乎等处,如果本文对你有帮助,记得为我得到我的个人技术博客项目给个star哦. 为何写这篇文章? 你可能做Web开发已经有一段时间, ...