案例6-1.7 公路村村通 (30分)
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。

输入格式:
输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。

输出格式:
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。

输入样例:

6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3

输出样例:

12

一.Prim算法

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MaxVertexNum 1000
#define INFINITY 65535
#define ERROR -1
typedef struct GNode* PtrToGNode;
struct GNode {int Nv, Ne;int G[MaxVertexNum][MaxVertexNum];
};
typedef PtrToGNode MGraph;
typedef struct ENode* PtrToENode;
struct ENode {int V1, V2;int Weight;
};
typedef PtrToENode Edge;
MGraph CreateGraph(int VertexNum) {int v, w;MGraph Graph = (MGraph)malloc(sizeof(struct GNode));Graph->Nv = VertexNum;Graph->Ne = 0;for (v = 1; v <= Graph->Nv; v++)for (w = 1; w <= Graph->Nv; w++)Graph->G[v][w] = INFINITY;return Graph;
}
void InsertEdge(MGraph Graph, Edge E) {Graph->G[E->V1][E->V2] = E->Weight;Graph->G[E->V2][E->V1] = E->Weight;
}
int FindMinDist(MGraph Graph, int dist[]) {int MinV, V;int MinDist = INFINITY;for (V = 1; V <= Graph->Nv; V++) {if (dist[V] != 0 && dist[V] < MinDist) {MinDist = dist[V];MinV = V;}}if (MinDist < INFINITY)return MinV;else return ERROR;
}
int parent[MaxVertexNum];
int Prim(MGraph Graph, MGraph MST) {int dist[MaxVertexNum], TotalWeight;int V, W;int VCount;Edge E;for (V = 1; V <= Graph->Nv; V++) {dist[V] = Graph->G[1][V];parent[V] = 1;}TotalWeight = 0;VCount = 0;E = (Edge)malloc(sizeof(struct ENode));dist[1] = 0;VCount++;parent[1] = 1;while (1) {V = FindMinDist(Graph, dist);if (V == ERROR)break;E->V1 = parent[V];E->V2 = V;E->Weight = dist[V];InsertEdge(MST, E);TotalWeight += dist[V];dist[V] = 0;VCount++;for (W = 1; W <= Graph->Nv; W++)if (dist[W] != 0 && Graph->G[V][W] < INFINITY) {if (Graph->G[V][W] < dist[W]) {dist[W] = Graph->G[V][W];parent[W] = V;}}}if (VCount < Graph->Nv)TotalWeight = ERROR;return TotalWeight;
}
int main() {MGraph Graph, MST;Edge E;int V, TotalWeight;int Nv, i;scanf("%d", &Nv);Graph = CreateGraph(Nv);MST = CreateGraph(Nv);scanf("%d", &(Graph->Ne));if (Graph->Ne != 0) {E = (Edge)malloc(sizeof(struct ENode));for (i = 1; i <= Graph->Ne; i++) {scanf("%d%d%d", &E->V1, &E->V2, &E->Weight);InsertEdge(Graph, E);}}TotalWeight = Prim(Graph,MST);printf("%d", TotalWeight);return 0;
}

二.Kruskal算法

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define MaxVertexNum 1000
typedef struct ENode* PtrToENode;
struct ENode {int V1, V2;int Weight;
};
typedef PtrToENode Edge;
typedef struct AdjVNode* PtrToAdjVNode;
struct AdjVNode {int AdjV;int Weight;PtrToAdjVNode Next;
};
typedef struct VNode {PtrToAdjVNode FirstEdge;
}AdjList[MaxVertexNum];
typedef struct GNode* PtrToGNode;
struct GNode {int Nv;int Ne;AdjList G;
};
typedef PtrToGNode LGraph;
LGraph CreateGraph(int VertexNum) {int V;LGraph Graph = (LGraph)malloc(sizeof(struct GNode));Graph->Nv = VertexNum;Graph->Ne = 0;for (V = 1; V <= Graph->Nv; V++)Graph->G[V].FirstEdge = NULL;return Graph;
}
void InsertEdge(LGraph Graph, Edge E) {PtrToAdjVNode NewNode;NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));NewNode->AdjV = E->V2;NewNode->Weight = E->Weight;NewNode->Next = Graph->G[E->V1].FirstEdge;Graph->G[E->V1].FirstEdge = NewNode;NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));NewNode->AdjV = E->V1;NewNode->Weight = E->Weight;NewNode->Next = Graph->G[E->V2].FirstEdge;Graph->G[E->V2].FirstEdge = NewNode;
}
LGraph BuildGraph() {LGraph Graph;Edge E;int Nv, i;scanf("%d", &Nv);Graph = CreateGraph(Nv);scanf("%d", &(Graph->Ne));if (Graph->Ne != 0) {E = (Edge)malloc(sizeof(struct ENode));for (i = 0; i < Graph->Ne; i++) {scanf("%d%d%d", &E->V1, &E->V2, &E->Weight);InsertEdge(Graph, E);}}return Graph;
}
int SetType[MaxVertexNum];
void InitializeVSet(int S[], int N) {int i;for (i = 1; i <= N; i++) {S[i] = -1;}
}
void Union(int S[], int Root1, int Root2) {if (S[Root1] > S[Root2]) {S[Root2] += S[Root1];S[Root1] = Root2;}else {S[Root1] += S[Root2];S[Root2] = Root1;}
}
int Find(int S[], int X) {if (S[X] < 0)return X;elsereturn S[X] = Find(S, S[X]);
}
bool CheckCycle(int* VSet, int V1, int V2) {int Root1;int Root2;Root1 = Find(VSet, V1);Root2 = Find(VSet, V2);if (Root1 == Root2)return false;else {Union(VSet, Root1, Root2);return true;}
}
void PercDown(Edge ESet, int p, int N) {int Child, Parent;struct ENode X = ESet[p];for (Parent = p; (Parent * 2 + 1) < N; Parent = Child) {Child = Parent * 2 + 1;if (Child != N - 1 && ESet[Child].Weight > ESet[Child + 1].Weight)Child++;if (X.Weight <= ESet[Child].Weight)break;else {ESet[Parent] = ESet[Child];}}ESet[Parent] = X;
}
void InitializeESet(LGraph Graph, Edge ESet) {int ECount = 0, V;PtrToAdjVNode W;for (V = 1; V < Graph->Nv; V++) {for (W = Graph->G[V].FirstEdge; W; W = W->Next) {if (V < W->AdjV) {/*避免重复录入无向边,只录入V1<V2的边*/ESet[ECount].V1 = V;ESet[ECount].V2 = W->AdjV;ESet[ECount++].Weight = W->Weight;}}}for (ECount = Graph->Ne / 2 ; ECount > 0; ECount--) {PercDown(ESet, ECount, Graph->Ne);}
}
void Swap(Edge a, Edge b) {struct ENode temp = *a;*a = *b;*b = temp;
}
int GetEdge(Edge ESet, int CurrentSize) {Swap(&ESet[0], &ESet[CurrentSize - 1]);PercDown(ESet, 0, CurrentSize - 1);return CurrentSize - 1;
}
int Kruskal(LGraph Graph, LGraph MST) {int TotalWeight;int ECount;int VSet[MaxVertexNum] = { 0 };InitializeVSet(VSet, Graph->Nv);Edge ESet = (Edge)malloc((Graph->Ne) * sizeof(struct ENode));InitializeESet(Graph, ESet);MST = CreateGraph(Graph->Nv);TotalWeight = 0;ECount = 0;int NextEdge = Graph->Ne;while (ECount < Graph->Nv - 1) {NextEdge = GetEdge(ESet, NextEdge);if (NextEdge < 0)break;if (CheckCycle(VSet, ESet[NextEdge].V1, ESet[NextEdge].V2)) {InsertEdge(MST, ESet + NextEdge);TotalWeight += ESet[NextEdge].Weight;ECount++;}}if (ECount < Graph->Nv - 1)TotalWeight = -1;elsereturn TotalWeight;
}
int main() {LGraph Graph = BuildGraph();LGraph MST = (LGraph)malloc(sizeof(LGraph));int TotalWeight = Kruskal(Graph, MST);printf("%d", TotalWeight);system("pause");return 0;
}

C语言实现Prim算法与Kruskal算法(浙大 陈越版)相关推荐

  1. Prim算法和Kruskal算法

       Prim算法和Kruskal算法都能从连通图找出最小生成树.区别在于Prim算法是以某个顶点出发挨个找,而Kruskal是先排序边,每次选出最短距离的边再找. 一.Prim(普里姆算法)算法: ...

  2. C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)

    1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...

  3. 【Java数据结构与算法】第十九章 贪心算法、Prim算法和Kruskal算法

    第十九章 贪心算法.Prim算法和Kruskal算法 文章目录 第十九章 贪心算法.Prim算法和Kruskal算法 一.贪心算法 1.介绍 2.支付问题 二.Prim算法 1.最小生成树 2.介绍 ...

  4. matlab实现prim算法,Prim算法和Kruskal算法的Matlab实现

    Prim算法和Kruskal算法的Matlab实现 <计算机仿真>期末大作业 Prim算法和Kruskal算法的Matlab实现 05605刘禹050697(30) 连线问题应用举例: 欲 ...

  5. 【最小生成树】Prim算法和Kruskal算法的区别对比

    Prim算法和Kruskal算法都是从连通图中找出最小生成树的经典算法- 从策略上来说,Prim算法是直接查找,多次寻找邻边的权重最小值,而Kruskal是需要先对权重排序后查找的- 所以说,Krus ...

  6. 加权无向图与最小生成树(Prim算法和Kruskal算法)

    目录 0 引入 1 图的最小生成树定义及相关约定 2 最小生成树原理 2.1 性质 2.2 切分定理 3 贪心思想 4 Prim算法 4.1 算法步骤 4.2 API设计 4.3 Java代码演示 5 ...

  7. 求的带权图最小生成树的Prim算法和Kruskal算法

    求的带权图最小生成树的Prim算法和Kruskal算法 最小生成树的概念 最小生成树其实是最小权重生成树的简称. 一个连通图可能有多个生成树.当图中的边具有权值时,总会有一个生成树的边的权值之和小于或 ...

  8. 数据结构与算法—最小生成树(Prim算法和Kruskal算法算法详解)

    前言 在数据结构与算法的图论中,(生成)最小生成树算法是一种常用并且和生活贴切比较近的一种算法.但是可能很多人对概念不是很清楚.我们看下百度百科对于最小生成树定义: 一个有 n 个结点的连通图的生成树 ...

  9. prim算法_求解最优树——Prim算法与Kruskal算法

    本文主要参考: 1.<Matlab数学建模算法全收录(数学建模比赛必备参考资料).pdf> 2.最小生成树-Prim算法和Kruskal算法 1 前言 简单来说,图由顶(就是结点)和边构成 ...

最新文章

  1. 一名毕业三年的女程序媛面试头条经验,重难点整理
  2. acwing算法题--01背包问题
  3. Python 代码实现模糊查询
  4. *** FATAL ERROR: too many grib files .. 1st=F:\data\预测数据 2nd=- ***
  5. ecshop商城禁止修改管理员邮箱
  6. LeetCode 1249. 移除无效的括号(栈+set / deque)
  7. 图解排序算法(三)之堆排序
  8. 2021年11月国产数据库排行榜:openGauss闯入前三,Kingbase流行度与日俱增,TDengine厚积薄发
  9. 自动化运维工具之Zabbix发现_自动注册及web页面状态监控(四)
  10. C++第五章课后习题-输入n个字符串,把其中以字母A打头的字符串输出
  11. Go语言之高级篇beego框架之模型(Models)
  12. 【更新】ReSharper v2018.3发布
  13. 微信小程序图片四个API用法
  14. c语言中eof的作用,eof在c语言中表示什么
  15. 无线网络 开启nat共享服务器,wifi共享大师开启NAT服务出错的解决方案
  16. Unity 截取3D图像 与 画中画PIP的实现
  17. 庖丁解牛linux内核 百度云,庖丁解牛Linux内核分析笔记-1
  18. 三菱fx2n plc用什么编程软件
  19. 分享个自己开发的夸克网盘资源搜索引擎
  20. python使用ffmpeg去掉视频片头和片尾

热门文章

  1. 四、点对点的传输层【网络全景图分析系列】
  2. 微机原理与接口技术——8255A的使用方法
  3. 恒生电子实习记录-10
  4. mysql无法连接的sha2加密问题
  5. Django使用容联云发送短信验证码时提示:172001,网络错误
  6. Linux 安装ssh和配置ssh
  7. 身份证最后一位的校验
  8. webview性能优化—webview预创建
  9. 应广单片机adc_应广单片机adc和pwm例程
  10. C语言的字符串输入gets()函数