1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 数据结构与算法A实验六图论---7-4 公路村村通(最小生成树Prime和Kruskal算法)

数据结构与算法A实验六图论---7-4 公路村村通(最小生成树Prime和Kruskal算法)

时间:2020-11-26 07:16:34

相关推荐

数据结构与算法A实验六图论---7-4 公路村村通(最小生成树Prime和Kruskal算法)

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

输入格式:

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

输出格式:

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

输入样例:

6 151 2 51 3 31 4 71 5 41 6 22 3 42 4 62 5 22 6 63 4 63 5 13 6 14 5 104 6 85 6 3

结尾无空行

输出样例:

12

结尾无空行

Prime算法代码实现

#include<bits/stdc++.h>using namespace std;int Map[1001][1001];int minCost[1001]; //记录与该顶点邻接的边的最小权值int visited[1001];int n, m;int Prime(){int i, sum = 0, v;for (i = 1; i <= n; i++)minCost[i] = 99999999; //初始化最大值minCost[1] = 0;while (1){v = -1;for (i = 1; i <= n; i++) //找到权值最小的边所对应的顶点{if (!visited[i] && (v == -1 || minCost[v] > minCost[i]))v = i;}if (v == -1)break; //说明顶点已经经过了if (minCost[v] == 99999999)return 0; //如果有个孤立顶点,最小权值不会变,可以判断图是否连通visited[v] = 1;sum += minCost[v];for (i = 1; i <= n; i++) //每次更新与顶点邻接的边的最小权值{if (Map[v][i])minCost[i] = min(minCost[i], Map[v][i]);}}for (i = 1; i <= n; i++){if (!visited[i])return 0;}return sum;}int main(){int c1, c2, cost;cin >> n >> m;for (int i = 1; i <= m; i++){cin >> c1 >> c2 >> cost;Map[c1][c2] = cost; //为0的值都是不关联的Map[c2][c1] = cost;}int sum = Prime();if (sum)cout << sum << endl;elsecout << -1 << endl;return 0;}

Kruskal算法代码实现

#include<bits/stdc++.h>using namespace std;typedef struct Edge {int u, v;int cost;}Edge;Edge edge[3002]; //边int father[1002];int n, m;bool cmp(Edge a, Edge b) //边,递增排序{return a.cost < b.cost;}int findFather(int x){if (father[x] == x)return x;return findFather(father[x]);}int Kruskal(){int sum = 0, cnt = 0;int fu, fv;for (int i = 0; i < m; i++){fu = findFather(edge[i].u);fv = findFather(edge[i].v);if (fu != fv) //同一父节点形成环则跳过{father[fu] = fv; //合并cnt++;sum += edge[i].cost;}}if (cnt == n - 1)return sum;elsereturn -1;}int main(){cin >> n >> m;for (int i = 0; i < m; i++){cin >> edge[i].u >> edge[i].v >> edge[i].cost;}sort(edge, edge + m, cmp);for (int i = 1; i <= n; i++) // 最初,每个顶点为一个独立集合 father[i] = i;int sum = Kruskal();cout << sum;}

1.Prime算法

Prime算法可以成为“加点法”,即每次迭代选择相连的最小代价边的对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。如下图所示:

Prim算法_杨氏计算机知识整理-CSDN博客_prim算法

#include<bits/stdc++.h> using namespace std;#define MAX 100 #define MAXCOST 0x7fffffff int graph[MAX][MAX];int prim(int graph[][MAX], int n){int lowcost[MAX];int mst[MAX];int i, j, min, minid, sum = 0;for (i = 2; i <= n; i++){lowcost[i] = graph[1][i];mst[i] = 1; //mst[]存放MST外的点i到MST最短距离时候对应的MST里的点标号}mst[1] = 0;for (i = 2; i <= n; i++) //要找出n-1个点为止{min = MAXCOST;minid = 0;for (j = 2; j <= n; j++){if (lowcost[j] < min && lowcost[j] != 0){min = lowcost[j];minid = j;}}sum += min;lowcost[minid] = 0;for (j = 2; j <= n; j++){if (graph[minid][j] < lowcost[j])//不更新的话,lowcost[j]存的只是上一时刻的Lowcost[j],MST外部的点到minid的距离会不会比到之前的MST里点得最小距离小?{lowcost[j] = graph[minid][j];mst[j] = minid; //点j到MST内的lowcot对应的MST里的点事minid}}}return sum;}

2.kruskal算法

克鲁斯卡尔(Kruskal)算法 可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。