普里姆算法(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. owncloud搭建

    使用OwnCloud建立属于自己私有的云存储网盘 OwnCloud概述: OwnCloud 一款文件主机服务软件,就是我们平时使用的云存储,不过这是在自己主机的服务器上建立属于自己的私有云,OwnCl ...

  2. js文字颜色闪烁

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

  3. codeblocks输出中文乱码解决办法

    在使用codeblocks进行编程的时候我发现控制台输出会出现中文乱码,就像这样: 所以很快我就问了老师,解决步骤如下: 一:如果源码是用codeblock编写的,打开Setting->Edit ...

  4. jQuery插件Validate

    一.导入js库 <script type="text/javascript" src="<%=path %>/validate/jquery-1.6.2 ...

  5. F - F(最小生成树)

    题意:连通各点最短距离,最小生成树. You are assigned to design network connections between certain points in a wide a ...

  6. CF-1440C2 Binary Table (Hard Version) (构造,模拟)

    Binary Table (Hard Version) 题意 \(n*m(2\le n,m\le 100)\) 的01矩阵,每次可以选择一个宽度为2的子矩阵,将四个位置中的任意3个进行翻转,即0变1, ...

  7. Educational Codeforces Round 91 (Rated for Div. 2) B. Universal Solution

    题目链接:https://codeforces.com/contest/1380/problem/B 题意 你在和一个机器人玩石头剪刀布,给出一个长为 $n$ 的出拳序列,机器人会从某一处开始出拳 $ ...

  8. 【poj 2891】Strange Way to Express Integers(数论--拓展欧几里德 求解同余方程组 模版题)

    题意:Elina看一本刘汝佳的书(O_O*),里面介绍了一种奇怪的方法表示一个非负整数 m .也就是有 k 对 ( ai , ri ) 可以这样表示--m%ai=ri.问 m 的最小值. 解法:拓展欧 ...

  9. Keywords Search HDU - 2222 AC自动机板子题

    In the modern time, Search engine came into the life of everybody like Google, Baidu, etc. Wiskey al ...

  10. MySQL 语句及其种类

    DDL(Data Definition Language) DDL(Data Definition Language),数据定义语言 CREATE:创建数据库和表等对象 DROP:删除数据库和表等对象 ...