最小生成树问题
1. 什么是最小生成树
- 是一棵树
- 无回路
- |V|个顶点一定有 |V|-1 条边
- 是生成树
- 不唯一
- 包含全部顶点
- |V|-1 条边都在图里
- 边的权值和最小
2. 贪心算法
- 什么是 “贪”:每一步都是最好的
- 什么是 “好”:权重最小的边
- 需要约束:
- 只能用图里有的边
- 只能正好用掉 |V|-1 条边
- 不能有回路
1. Prim 算法
void Prim(){
MST = {
s}; // parent[s] = -1
while(1){
V = 未收录顶点中dist最小者; // dist[V] = E<V,W> 或 正无穷
if ( 这样的V不存在 )
break;
dist[V] = 0; // 将V收录进MST
for ( V 的每个邻接点 W )
if ( dist[W]!= 0)
if ( E<V,W> < dist[w] ){
dist[W] = E<V,W>;
parent[W] = V;
}
}
if ( MST 中收的顶点不到|V|个)
Error ( "图不连通" );
}
时间复杂度:T = O(|V|2^22) —— 稠密图合算
#include<iostream>
#include<vector>
#define INF 100000
#define MaxVertex 105
typedef int Vertex;
int G[MaxVertex][MaxVertex];
int parent[MaxVertex]; // 并查集
int dist[MaxVertex]; // 距离
int Nv; // 结点
int Ne; // 边
int sum; // 权重和
using namespace std;
vector<Vertex> MST; // 最小生成树
// 初始化图信息
void build(){
Vertex v1,v2;
int w;
cin>>Nv>>Ne;
for(int i=1;i<=Nv;i++){
for(int j=1;