定义

在一给定的无向联通带权图\(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. excel-删除

    问题[1]:删除不整齐数据. 1 编号 单词本身 词性 命名实体 依存句法父节点 依存句法 谓词 语义角色 2 0 < wp O 1 WP _ - 3 1 弄臣 n O -1 HED _ - 4 ...

  2. Cayley-Hamilton 定理简要证明

    证明思路来源于 DZYO 发的博客 Cayley-Hamilton 定理: 设 \(\textbf A\) 是 n阶矩阵,\(f(\lambda)=\det(\lambda\textbf I-\tex ...

  3. Python 为什么能支持任意的真值判断?

    本文出自"Python为什么"系列,请查看全部文章 Python 在涉及真值判断(Truth Value Testing)时,语法很简便. 比如,在判断某个对象是否不为 None ...

  4. html定时跳转页面

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. DRF内置认证组件之自定义认证系统

    自定义token认证 我们知道,在django项目中不管路由以及对应的视图类是如何写的,都会走到 dispatch 方法,进行路由分发, 在阅读 APIView类中的dispatch 方法的源码中,有 ...

  6. CPF 入门教程 - 数据绑定和命令绑定(二)

    CPF netcore跨平台UI框架 系列教程 CPF 入门教程(一) CPF 入门教程 - 数据绑定和命令绑定(二) 数据绑定和Wpf类似,支持双向绑定.数据绑定和命令绑定是UI和业务逻辑分离的基础 ...

  7. 机器学习 | 详解GBDT在分类场景中的应用原理与公式推导

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题的第31篇文章,我们一起继续来聊聊GBDT模型. 在上一篇文章当中,我们学习了GBDT这个模型在回归问题当中的原理.GBD ...

  8. 【支付宝SDK】沙箱调试,以及遇到的坑

    from rest_framework.views import APIView from alipay import AliPay, DCAliPay, ISVAliPay from django. ...

  9. 第3章 Hive数据类型

    第3章 Hive数据类型 3.1 基本数据类型 对于Hive的String类型相当于数据库的varchar类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它可以存储2GB ...

  10. 原生js实现 vue的数据双向绑定

    原生js实现一个简单的vue的数据双向绑定 vue是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时 ...