定义

在一给定的无向联通带权图\(G = (V, E, W)\)中,\((u, v)\) 代表连接顶点 \(u\) 与顶点 \(v\) 的边,而 \(w(u, v)\) 代表此边的权重,若存在 \(T\) 为 \(E\) 的子集,且为无循环图,使得 \(w(T)\) 最小,则此 \(T\) 为 \(G\) 的最小生成树

其中\(w(T)=\sum\limits_{(u,v)∈t} w(u,v)\)

由定义易得,\(T\)中的边数为 顶点个数\(-1\)。

实现算法常用\(Kruskal\)和\(Prim\)

\(Kruskal\)算法

将边按权值从小到大排序再依次放入图中,当整个图只有一个连通分量时,程序结束。

实现方法

  • 1.找到\(E\)中最小边
  • 2.判断边的两点是否在同一连通分量中
  • 3.若在,舍弃此边,转1。
  • 4.若不在,添加此边,将端点所在连通分量合并。
  • 5.所有边全选完后,若选边数为n-1,则输出解,否则无解处理。

代码:

#include <bits/stdc++.h>
using namespace std;
const int EDG=1000010;
const int VER=100010;
int n,m;
struct edge
{
int _start;
int _end;
int _weigh;
} arc[EDG];/*结构体存边,便于排序*/
bool cmp(edge a,edge b)
{
return a._weigh<b._weigh;
}
int parent[VER];
inline void init();
inline int find(int x);
int union_(int x,int y);
inline bool search_(int x,int y); int main()
{
init();
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>arc[i]._start>>arc[i]._end>>arc[i]._weigh;
}
if(m<n-1)//如果不够n-1条边,直接无解
{
cout<<"orz";
return 0;
}
sort(arc+1,arc+1+m,cmp);//权值排序
int num=0;
int ans=0;
for(int i=1;i<=m;i++)
{
if(!search_(arc[i]._start,arc[i]._end))//如果边的端点不在同一个连通分量中
{
ans+=arc[i]._weigh;//选择这条边
union_(arc[i]._end,arc[i]._start);//合并两个连通分量
num++;//选择的边数 +1
}
}
if(num==n-1)//最小生成树只可能有n-1条边
{
cout<<ans;
}
else cout<<"orz";
} /*----------并查集相关----------*/
inline void init()
{
for(int i=0;i<=VER;i++)
{
parent[i]=i;
}
}
inline int find(int x)
{
int x_root=x;
while(x_root!=parent[x_root])
{
x_root=parent[x_root];
}
while(x!=x_root)
{
int tmp=parent[x];
parent[x]=x_root;
x=tmp;
}
return x_root;
}
int union_(int x,int y)
{
int x_root=find(x);
int y_root=find(y);
if(x_root==y_root) return 0;
parent[x_root]=y_root;
return 1;
}
inline bool search_(int x,int y)
{
return find(x)==find(y);
}

\(Prim\)算法

其实就是\(dijksrta\)的变种,配合理解即可

#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int edg[1010][1010];
int dis[100010];
int vis[100010];
int n; void prim()
{
int sum=0;
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) dis[i]=edg[1][i];
vis[1]=1;
dis[1]=1;
for(int i=1;i<n;i++)
{
int minn=INF;
int u;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&minn>dis[j])
{
u=j;
minn=dis[j];
}
}
vis[u]=1;
sum+=minn;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&edg[u][j]<dis[j])
{
dis[j]=edg[u][j];
}
}
}
cout<<sum;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>edg[i][j];
}
}
prim();
return 0;
}

最小生成树MST的更多相关文章

  1. 最小生成树MST算法(Prim、Kruskal)

    最小生成树MST(Minimum Spanning Tree) (1)概念 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边,所谓一个 ...

  2. POJ 1679 The Unique 次最小生成树 MST

    http://poj.org/problem?id=1679 题目大意: 给你一些点,判断MST(最小生成树)是否唯一. 思路: 以前做过这题,不过写的是O(n^3)的,今天学了一招O(n^2)的,哈 ...

  3. 最小生成树(MST)[简述][模板]

    Prim(添点法) 1. 任选一点(一般选1), 作为切入点,设其与最小生成树的距离为0(实际上就是选一个点,将此树实体化),. 2. 在所有未选择的点中选出与最小生成树距离最短的, 累计其距离, 并 ...

  4. 【算法与数据结构】图的最小生成树 MST - Prim 算法

    Prim 算法属于贪心算法. #include <stdio.h> #define VERTEXNUM 7 #define INF 10000 typedef struct Graph { ...

  5. MST最小生成树及克鲁斯卡尔(Kruskal)算法

    最小生成树MST,英文名如何拼写已忘,应该是min spaning tree吧.假设一个无向连通图有n个节点,那么它的生成树就是包括这n个节点的无环连通图,无环即形成树.最小生成树是对边上权重的考虑, ...

  6. Hdu 4081 最小生成树

    Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/3 ...

  7. 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind

    最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...

  8. 最小生成树算法prim and kruskal

    一.最小生成树定义:  从不同顶点出发或搜索次序不同,可得到不同的生成树  生成树的权:对连通网络来说,边附上权,生成树也带权,我们把生成树各边的权值总和称为生成树的权  最小代价生成树:在一个连通网 ...

  9. CF1108F MST Unification

    题目地址:CF1108F MST Unification 最小生成树kruskal算法的应用 只需要在算法上改一点点 当扫描到权值为 \(val\) 的边时,我们将所有权值为 \(val\) 的边分为 ...

随机推荐

  1. C语言学习笔记之输出缓冲

    在c语言中经常用到输出函数printf,当我们像往常一样在输出函数中输入我们的想要的输出的东西后加\n换行 验证结果如我们输出的一样 如果我们在后面加入死循环会不会出现这些语句呢 结果卡死了,可还是输 ...

  2. easyPOI使用

    更多的easyPOI资源的网在easypoi的官网. 1 在pom.xml中添加依赖 <dependency> <groupId>cn.afterturn</groupI ...

  3. C#LeetCode刷题-队列

    队列篇 # 题名 刷题 通过率 难度 363 矩形区域不超过 K 的最大数值和   27.2% 困难 621 任务调度器   40.9% 中等 622 设计循环队列 C#LeetCode刷题之#622 ...

  4. JavaScript map+parseInt 容易产生的误区

    map /** * 语法: * var new_array = arr.map(function callback(currentValue[,index[,array]]){ * // return ...

  5. 旧 WCF 项目迁移到 asp.net core + gRPC 的尝试

    一个月前,公司的运行WCF的windows服务器down掉了,由于 AWS 没有通知,没有能第一时间发现问题. 所以,客户提出将WCF服务由C#改为JAVA,在Linux上面运行:一方面,AWS对Li ...

  6. BufferedReader、BufferedWriter读写文件乱码问题:

    代码: text4500.txt文档用text打开(不知道格式): 读取会出现乱码,然后用Notepad++打开换成UTF-8格式的.就可以了

  7. JS精度损失toFixed

    1234*0.01=12.3400000001 很明显后缀00001跟预期想要的不一致,起初面临这个问题我的处理方式是这样的: (1234*0.01).toString().substring(0,2 ...

  8. Alink漫谈(十九) :源码解析 之 分位点离散化Quantile

    Alink漫谈(十九) :源码解析 之 分位点离散化Quantile 目录 Alink漫谈(十九) :源码解析 之 分位点离散化Quantile 0x00 摘要 0x01 背景概念 1.1 离散化 1 ...

  9. IDEA编写Scala代码时自动显示变量类型

    设置方法如下:settins -->Editor--> Code Style --> scala --Type Annotations  勾选框选部分 测试效果

  10. StructuredStreaming编程模型

    StructuredStreaming编程模型 基本概念 ◆ Time ◆ Trigger ◆ Input ◆ Query ◆ Result ◆ Output  案例模型:实时处理流单词统计编程模型 ...