普里姆算法(Prim算法)

#include<bits/stdc++.h>
using namespace std;
#define MAXVEX 100
#define INF 65535
typedef char VertexType;
typedef int EdgeType;
typedef struct {
VertexType vexs[MAXVEX];
EdgeType arc[MAXVEX][MAXVEX];
int numVertexes, numEdges;
}MGraph; void CreateMGraph(MGraph *G) {
int m, n, w; //vm-vn的权重w
scanf("%d %d", &G->numVertexes, &G->numEdges); for(int i = 0; i < G->numVertexes; i++) {
getchar();
scanf("%c", &G->vexs[i]);
} for(int i = 0; i < G->numVertexes; i++) {
for(int j = 0; j < G->numVertexes; j++) {
if(i == j) G->arc[i][j] = 0;
else G->arc[i][j] = INF;
}
}
for(int k = 0; k < G->numEdges; k++) {
scanf("%d %d %d", &m, &n, &w);
G->arc[m][n] = w;
G->arc[n][m] = G->arc[m][n];
}
} void MiniSpanTree_Prim(MGraph G) {
int min, j, k;
int arjvex[MAXVEX]; //最小边在 U集合中的那个顶点的下标
int lowcost[MAXVEX]; // 最小边上的权值
//初始化,从点 V0开始找最小生成树T
arjvex[0] = 0; //arjvex[i] = j表示 V-U中集合中的 Vi点的最小边在U集合中的点为 Vj
lowcost[0] = 0; //lowcost[i] = 0表示将点Vi纳入集合 U ,lowcost[i] = w表示 V-U中 Vi点到 U的最小权值
for(int i = 1; i < G.numVertexes; i++) {
lowcost[i] = G.arc[0][i];
arjvex[i] = 0;
}
//根据最小生成树的定义:从n个顶点中,找出 n - 1条连线,使得各边权值最小
for(int i = 1; i < G.numVertexes; i++) {
min = INF, j = 1, k = 0;
//寻找 V-U到 U的最小权值min
for(j; j < G.numVertexes; j++) {
// lowcost[j] != 0保证顶点在 V-U中,用k记录此时的最小权值边在 V-U中顶点的下标
if(lowcost[j] != 0 && lowcost[j] < min) {
min = lowcost[j];
k = j;
}
}
}
printf("V[%d]-V[%d] weight = %d\n", arjvex[k], k, min);
lowcost[k] = 0; //表示将Vk纳入 U
//查找邻接矩阵Vk行的各个权值,与lowcost的对应值进行比较,若更小则更新lowcost,并将k存入arjvex数组中
for(int i = 1; i < G.numVertexes; i++) {
if(lowcost[i] != 0 && G.arc[k][i] < lowcost[i]) {
lowcost[i] = G.arc[k][i];
arjvex[i] = k;
}
} } int main() {
MGraph *G = (MGraph *)malloc(sizeof(MGraph));
CreateMGraph(G);
MiniSpanTree_Prim(*G);
} /*
input:
4 5
a
b
c
d
0 1 2
0 2 2
0 3 7
1 2 4
2 3 8 output:
V[0]-V[1] weight = 2
V[0]-V[2] weight = 2
V[0]-V[3] weight = 7
最小总权值: 11
*/

时间复杂度O(n^2)

克鲁斯卡尔算法(Kruskal算法)

#include<bits/stdc++.h>
using namespace std;
#define MAXVEX 100
#define MAXEDGE 100
#define INF 65535
typedef char VertexType;
typedef int EdgeType;
//图的邻接矩阵存储结构的定义
typedef struct {
VertexType vexs[MAXVEX];
EdgeType arc[MAXVEX][MAXVEX];
int numVertexes, numEdges;
}MGraph; //边集数组Edge结构的定义
typedef struct {
int begin;
int end;
int weight;
}Edge; bool vis[100][100]; void CreateMGraph(MGraph *G) {
int m, n, w; //vm-vn的权重w
scanf("%d %d", &G->numVertexes, &G->numEdges); for(int i = 0; i < G->numVertexes; i++) {
getchar();
scanf("%c", &G->vexs[i]);
} for(int i = 0; i < G->numVertexes; i++) {
for(int j = 0; j < G->numVertexes; j++) {
if(i == j) G->arc[i][j] = 0;
else G->arc[i][j] = INF;
}
}
for(int k = 0; k < G->numEdges; k++) {
scanf("%d %d %d", &m, &n, &w);
G->arc[m][n] = w;
G->arc[n][m] = G->arc[m][n];
}
} void MiniSpanTree_Kruskal(MGraph G) {
int v1, v2, vs1, vs2;
Edge edges[MAXEDGE];
int parent[MAXVEX]; //标记各顶点所属的连通分量,用于判断边与边是否形成环路 //将邻接矩阵转换成按权值从小到大排序的边集数组
/* */
int tmp = 0, m, n, ans;
ans = (G.numVertexes*G.numVertexes) / 2 - G.numVertexes / 2;
for(int k = 0; k < ans; k++) {
int min = INF, i, j;
for(i = 0; i < G.numVertexes; i++) {
for(j = 0; j < G.numVertexes; j++) {
if(!vis[i][j] && i < j && min > G.arc[i][j]) {
min = G.arc[i][j];
m = i;
n = j;
}
}
}
if(G.arc[i][j] == INF)
continue;
edges[tmp].begin = m;
edges[tmp].end = n;
edges[tmp].weight = min;
vis[m][n] = true;
tmp++;
} //初始化为各顶点各自为一个连通分量
for(int i = 0; i < G.numVertexes; i++)
parent[i] = i; for(int i = 0; i < G.numEdges; i++) {
//起点终点下标
v1 = edges[i].begin;
v2 = edges[i].end;
//起点终点连通分量
vs1 = parent[v1];
vs2 = parent[v2];
//边的两个顶点属于不同的连通分量,打印,将新来的连通分量更改为起始点的连通分量
if(vs1 != vs2) {
printf("V[%d]-V[%d] weight:%d\n", edges[i].begin, edges[i].end, edges[i].weight);
for(int j = 0; j < G.numVertexes; j++) {
if(parent[j] == vs2) parent[j] = vs1;
}
}
}
} int main() {
MGraph *G = (MGraph *)malloc(sizeof(MGraph));
CreateMGraph(G);
MiniSpanTree_Kruskal(*G);
} /*
input:
4 5
a
b
c
d
0 1 2
0 2 2
0 3 7
1 2 4
2 3 8 output:
V[0]-V[1] weight = 2
V[0]-V[2] weight = 2
V[0]-V[3] weight = 7
最小总权值: 11
*/

时间复杂度O(elog2e) e为边数

最小生成树---普里姆算法(Prim算法)和克鲁斯卡尔算法(Kruskal算法)的更多相关文章

  1. 图->连通性->最小生成树(普里姆算法)

    文字描述 用连通网来表示n个城市及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的权值表示相应的代价.对于n个定点的连通网可以建立许多不同的生成树,每一棵生成树都可 ...

  2. 图解最小生成树 - 普里姆(Prim)算法

    我们在图的定义中说过,带有权值的图就是网结构.一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边.所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接 ...

  3. hdu 1233:还是畅通工程(数据结构,图,最小生成树,普里姆(Prim)算法)

    还是畅通工程 Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  4. 普里姆(Prim)算法

    概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图(即"带权图")里搜索最小生成树.即此算法搜索到的边(Edge)子集所构成的树中,不但包括了连通图里的所有顶点(V ...

  5. HDU 1162 Eddy's picture (最小生成树 普里姆 )

    题目链接 Problem Description Eddy begins to like painting pictures recently ,he is sure of himself to be ...

  6. 最小生成树 - 普里姆 - 边稠密 - O(N ^ 2)

    #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #define N 1005 #def ...

  7. 最小生成树之克鲁斯卡尔(Kruskal)算法

    学习最小生成树算法之前我们先来了解下 下面这些概念: 树(Tree):如果一个无向连通图中不存在回路,则这种图称为树. 生成树 (Spanning Tree):无向连通图G的一个子图如果是一颗包含G的 ...

  8. 经典问题----最小生成树(prim普里姆贪心算法)

    题目简述:假如有一个无向连通图,有n个顶点,有许多(带有权值即长度)边,让你用在其中选n-1条边把这n个顶点连起来,不漏掉任何一个点,然后这n-1条边的权值总和最小,就是最小生成树了,注意,不可绕成圈 ...

  9. 最小生成树 Prim(普里姆)算法和Kruskal(克鲁斯特尔)算法

    Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...

随机推荐

  1. Apache Cocoon XML注入 [CVE-2020-11991]

    受影响版本: Apache Cocoon <= 2.1.x 程序使用了StreamGenerator这个方法时,解析从外部请求的xml数据包未做相关的限制,恶意用户就可以构造任意的xml表达式, ...

  2. CentOS 安装TFTP

    1.当然是使用yum安装最直接,一共会安装3个东东tftp.i386tftp-server.i386xinetd.i386[root@localhost CentOS]# yum -y install ...

  3. Dedecms织梦搜索页显示条数的更改方法

    织梦dedecms搜索结果页面的显示条数默认是10条,这个数值在模板当中是不能控制的. 解决方法: 打开根目录下的plus文件夹,找到search.php修改一段代码: 在大概第15行,找到 $ pa ...

  4. mysql高级day1

    Mysql高级-day01 MySQL高级课程简介 序号 Day01 Day02 Day03 Day04 1 Linux系统安装MySQL 体系结构 应用优化 MySQL 常用工具 2 索引 存储引擎 ...

  5. memcache安装及解决无法远程连接的问题

    Memcached是什么 Memcached是一个自由开源的,高性能,分布式内存对象缓存系统. Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fit ...

  6. C++多元组tuple使用方法?你熟悉吗?快来看看吧

  7. 洛谷P4719 【模板】"动态 DP"&动态树分治

    [模板]"动态 DP"&动态树分治 第一道动态\(DP\)的题,只会用树剖来做,全局平衡二叉树什么的就以后再学吧 所谓动态\(DP\),就是在原本的\(DP\)求解的问题上 ...

  8. K - Japan(线段树)

    Japan plans to welcome the ACM ICPC World Finals and a lot of roads must be built for the venue. Jap ...

  9. Codeforces Round #307 (Div. 2) B. ZgukistringZ

    Professor GukiZ doesn't accept string as they are. He likes to swap some letters in string to obtain ...

  10. hdu5317 RGCDQ

    Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more an ...