定义

在一给定的无向联通带权图\(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语言学习笔记之进制之间的转换

    这一篇主要是对进制之间转换的讲解,方便查看,以防忘记 二进制      逢二进一 八进制      逢八进一                以0开头, 0就是8进制的标志 十进制      逢十进一 ...

  2. 22、Command 命令模式

    1.command 命令模式 命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指 ...

  3. Python学习笔记之 Python设计思想&设计原则

    Python设计思想&设计原则 设计思想 1.封装 数据角度 多种数据合为一种数据 优势:代码可读性高            将数据与行为相关联 例如:电脑(内存,储存空间,...) 行为角度 ...

  4. Java 变量及运算符

    Java概述 Java的发展可以归纳如下的几个阶段: (1)第一阶段(完善期):JDK 1.0 ( 1995年推出)一JDK 1.2 (1998年推出,Java更名为Java 2): (2)第二阶段( ...

  5. HTML基础-01

    HTML:超文本标记语言,是一种使用结构化Web网页(标准制定者:W3C)及其内容的标记语言. 发展过程:XHTML5,HTML5,XHTML1.0,HTML4.01,HTML3.2 HTML5特性: ...

  6. 虚拟机安装mysql遇到的坑

    相信很多同学也跟我一样在家里,windows安装个虚拟机,再安装linux.然后在linux下模拟出一套运行环境.这次我装的是mysql 8.0.中间遇到很多坑,记录一下.(用的linux为redha ...

  7. 导出Excel文件(项目中会遇到很多将一些数据导出Excel或者et)

    最近在项目中,遇到一些需求,就是将数据导出来,以Excel文件为主:就自己简单的做一些demo:供初学者来学习: // 定义一个保存文件的路径位置 SaveFileDialog dlgPath = n ...

  8. unity探索者之安卓微信登录,非第三方插件

    版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/7666348.html 之前写了两篇关于微信分享的博客,其实微信登录.分享.支付博主 ...

  9. IDEA_Shelve代码搁置与恢复

    日常开发中,经常会遇到在当前分支开发到一半,但是需要Checkout上个版本解决bug或调查问题的情况.这个时候,我们是将代码提到Push远程?还是直接Rollback? 最理想的做法,就是将当前的开 ...

  10. 你所不知道的Spring的@Autowired实现细节

    前言 相信很多Java开发都遇到过一个面试题:Resource和Autowired的区别是什么?这个问题的答案相信基本都清楚,但是这两者在Spring中是如何实现的呢?这就要分析Spring源码才能知 ...