最小生成树MST
定义
在一给定的无向联通带权图\(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的更多相关文章
- 最小生成树MST算法(Prim、Kruskal)
最小生成树MST(Minimum Spanning Tree) (1)概念 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边,所谓一个 ...
- POJ 1679 The Unique 次最小生成树 MST
http://poj.org/problem?id=1679 题目大意: 给你一些点,判断MST(最小生成树)是否唯一. 思路: 以前做过这题,不过写的是O(n^3)的,今天学了一招O(n^2)的,哈 ...
- 最小生成树(MST)[简述][模板]
Prim(添点法) 1. 任选一点(一般选1), 作为切入点,设其与最小生成树的距离为0(实际上就是选一个点,将此树实体化),. 2. 在所有未选择的点中选出与最小生成树距离最短的, 累计其距离, 并 ...
- 【算法与数据结构】图的最小生成树 MST - Prim 算法
Prim 算法属于贪心算法. #include <stdio.h> #define VERTEXNUM 7 #define INF 10000 typedef struct Graph { ...
- MST最小生成树及克鲁斯卡尔(Kruskal)算法
最小生成树MST,英文名如何拼写已忘,应该是min spaning tree吧.假设一个无向连通图有n个节点,那么它的生成树就是包括这n个节点的无环连通图,无环即形成树.最小生成树是对边上权重的考虑, ...
- Hdu 4081 最小生成树
Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind
最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...
- 最小生成树算法prim and kruskal
一.最小生成树定义: 从不同顶点出发或搜索次序不同,可得到不同的生成树 生成树的权:对连通网络来说,边附上权,生成树也带权,我们把生成树各边的权值总和称为生成树的权 最小代价生成树:在一个连通网 ...
- CF1108F MST Unification
题目地址:CF1108F MST Unification 最小生成树kruskal算法的应用 只需要在算法上改一点点 当扫描到权值为 \(val\) 的边时,我们将所有权值为 \(val\) 的边分为 ...
随机推荐
- python6.3类的继承与多态
class Animal(object): def __init__(self,color): self.color=color def eat(self): print("动物在吃!&qu ...
- Hexo小技巧(包括如何插入本地图片)
我在研究如何在Hexo中引用本地图片时,看到官方文档对此问题已给出了解决方法,并亲测有效.当然,我并不满足于仅仅知道这一个技巧.在大致阅读过官方文档后,我总结了之前我个人并不知道的几个关于Hexo写博 ...
- 007_对go语言中的自定义排序sort的小练习
在go语言基础知识中,有个知识点是go语言的自定义排序,我在学习完之后,自己做了一些小练习和总结. 首先按照惯例,还是呈上代码演示: package main import "fmt&quo ...
- SpringBoot+Mybatis关于开启驼峰映射的设置
mybatis自定义的SQL语句中,如select语句,如果数据库表的字段为驼峰命名,即如img_address这样的形式,那么select语句执行的结果会变成null. 解决办法是在配置文件中加上开 ...
- Python学习笔记之 Python设计思想&设计原则
Python设计思想&设计原则 设计思想 1.封装 数据角度 多种数据合为一种数据 优势:代码可读性高 将数据与行为相关联 例如:电脑(内存,储存空间,...) 行为角度 ...
- Java Redis系列3(Jedis的使用+jedis连接池技术)
Jedis的使用 什么是Jedis? 一款Java操作redis数据库的工具 使用步骤 1.下载redis所需的java包 2.使用步骤 import org.junit.Test; public c ...
- java System类、Math类、Arrays类
一 System类 1.概念 在API中System类介绍的比较简单,我们给出定义,System中代表程序所在系统,提供了对应 的一些系统属性信息,和系统操作. System类不能手动创建对象,因为构 ...
- ECharts 常见的问题总结
以前也用过ECharts(不得不说,这真的是百度的良心产品),但是都是一些简单的示例.这次因为工作的需要,做了很多表格,对ECharts有了更加深刻的理解,现在来总结一下. 第一个肯定是新手经常遇到的 ...
- Java indexof
java中字符串方法 indexof() indexof()可以返回输入的字符串在目标字符串中第一次出现的位置,如果没有出现返回int 0:
- 一文看懂 Netty 架构设计
本文重点分析 Netty 的逻辑架构及关键的架构质量属性,希望有助于大家从 Netty 的架构设计中汲取营养,设计出高性能.高可靠性和可扩展的程序. Netty 的三层架构设计 Netty 采用了典型 ...