当前位置: 首页 > news >正文

C++最小生成树

最小生成树:

算法第一步,建图,任何算法均需要考虑,用什么结构去存储,这个算法使用邻接矩阵来存储,有时候输入数据,不是我们期待的那样,所以需要对数据进行一些处理,也就是将图建起来的过程

第二步,辅助数组,对于图G=<V, E>,源点为0(为什么),dist[i]表示顶点i与已生成的最小生成树之间的最小距离,visited[i]表示dist[i]是否已经确定,即i所在的最小生成数的边是否确定。

第三步,初始化,所有顶点的数据见下,

dist[i] = graph[0][i] (0<= i <= n)

visited[i] = false (0<= i <=n)

visited[0] = true

sum = 0

第四步,找边权最小的点,从所有visited[i]为false的点中找到一个dist[i]值最小的,令x=i,并且找到visited[x]标记为true,如果找不到,算法结束。

第五步,统计边权和,将当前找到的最小边权dist[x]累加到sum上,并且标记visited[x]为true

第六步,更新其余点的最小边权,更新目前最小生成树中所有节点到y的边权,取最小的 dist[y] = min(dist[y], w(x, y))

第七步,回到第四步,继续找边权最小的点

代码分析:

第一步,初始化邻接矩阵

function initEdge(graph, n)

  for u-> (0, n-1)

    for v-> (0, n-1)

      graph[u][v] = inf

第二步,边的添加

function addEdge(graph, u, v, w)

  graph[u][v] = min(graph[u][v], w)

  graph[v][u] = min(graph[v][u], w)

第三步,建图

addEdge(graph, u1, v1, w1)

addEdge(graph, u2, v2, w2)

...

第四步,框架代码

function Prim(graph, n, dist)

  visited[]

  sum=0

  PrimInit(n, visited, dist)

  while true

    u = PrimFindMin(n, visited, dist)

    if u == -1 return sum

    sum += dist[u]

    PrimUpdate(graph, n, u, visited, dist)

第五步,Prim初始化

function PrimInit(n, visited,dist)

  for i-> (0, n-1)

    visited[i] = false

    dist[i] = graph[0][i]

visited[0] = true

第六步,Prim找边权最小的点

function PrimFindMin(n, visited, dist)

  u = -1

  for i -> (0, n-1)

    if(visited[i]) continue

    if u == -1 or dist[i] < dist[u]

      u = i

 return u

第七步 Prim 更新

function PrimUpdate(graph, n, u, visited, dist)

  visited[u] = true

  for i -> (0, n-1)

    if visited[i] continue

    dist[i] = min(dist[i], graph[u][i])

代码练习 1 对应力扣 城邦 代码见下

#include <iostream>
using namespace std;#define maxn 2022
#define edgeType int
#define inf 1000000000void initEdge(int n, edgeType graph[maxn][maxn]){for(int i=0; i<n; ++i){for(int j=0; j<n; ++j){graph[i][j] = (i == j ? 0:inf); }}
}void addEdge(edgeType graph[maxn][maxn], int u, int v, edgeType w){if(w < graph[u][v]){graph[u][v] = w;}if(w < graph[v][u]){graph[v][u] = w;}
}edgeType prim(int n, edgeType graph[maxn][maxn]){int visited[maxn] = {0};edgeType dist[maxn];edgeType sum = 0;for(int i=0; i<n; ++i){dist[i] = graph[0][i];}visited[0] = 1;while(1){edgeType minDist = inf;int minIndex = -1;for(int i=0; i<n; ++i){if(!visited[i] && dist[i] < minDist){minDist = dist[i];minIndex = i;}}if(minIndex == -1){break;}sum += minDist;visited[minIndex] = 1;for(int i=0; i<n; ++i){if(!visited[i] && graph[minIndex][i] < dist[i]){dist[i] = graph[minIndex][i];}}}for(int i=0; i<n; ++i){if(!visited[i]){return -1;}}return sum;
}
edgeType graph[maxn][maxn];
int main()
{initEdge(2021, graph);for(int i=1; i <= 2021; ++i){for(int j=i+1; j<=2021; ++j){int u = i, v = j;edgeType w = 0;while(u || v){if(u%10 != v%10){w += u%10 + v%10;}u /= 10;v /= 10;}addEdge(graph, i-1, j-1, w);}}cout << prim(2021, graph) << endl;// 请在此输入您的代码return 0;
}

代码练习 2 对应蓝桥云课 通电 代码见下

#include <iostream>
#include <cmath>
using namespace std;#define maxn 1001
#define edgeType double
#define inf 1000000000void initEdge(int n, edgeType graph[maxn][maxn]){for(int i=0; i<n; ++i){for(int j=0; j<n; ++j){graph[i][j] = (i == j ? 0:inf); }}
}void addEdge(edgeType graph[maxn][maxn], int u, int v, edgeType w){if(w < graph[u][v]){graph[u][v] = w;}if(w < graph[v][u]){graph[v][u] = w;}
}edgeType prim(int n, edgeType graph[maxn][maxn]){int visited[maxn] = {0};edgeType dist[maxn];edgeType sum = 0;for(int i=0; i<n; ++i){dist[i] = graph[0][i];}visited[0] = 1;while(1){edgeType minDist = inf;int minIndex = -1;for(int i=0; i<n; ++i){if(!visited[i] && dist[i] < minDist){minDist = dist[i];minIndex = i;}}if(minIndex == -1){break;}sum += minDist;visited[minIndex] = 1;for(int i=0; i<n; ++i){if(!visited[i] && graph[minIndex][i] < dist[i]){dist[i] = graph[minIndex][i];}}}for(int i=0; i<n; ++i){if(!visited[i]){return -1;}}return sum;
}
int n;
int x[maxn], y[maxn], h[maxn];
edgeType graph[maxn][maxn];int SQR(int x){return x*x;
}int main()
{cin >> n;for(int i=0; i<n; ++i){cin >> x[i] >> y[i] >> h[i];}initEdge(n, graph);for(int i=0; i<n; ++i){for(int j = i+1; j<n; ++j){edgeType w = sqrt(SQR(x[i] - x[j]) + SQR(y[i] - y[j])) + SQR(h[i] - h[j]);addEdge(graph, i, j, w);}}// 请在此输入您的代码printf("%.2lf\n", prim(n, graph));return 0;
}

代码练习 3,对应蓝桥云课 繁忙的都市,代码见下

#include <iostream>
#include <cmath>
using namespace std;#define maxn 300
#define edgeType int
#define inf 1000000000void initEdge(int n, edgeType graph[maxn][maxn]){for(int i=0; i<n; ++i){for(int j=0; j<n; ++j){graph[i][j] = (i == j ? 0:inf); }}
}void addEdge(edgeType graph[maxn][maxn], int u, int v, edgeType w){if(w < graph[u][v]){graph[u][v] = w;}if(w < graph[v][u]){graph[v][u] = w;}
}edgeType prim(int n, edgeType graph[maxn][maxn]){int visited[maxn] = {0};edgeType dist[maxn];edgeType sum = 0;for(int i=0; i<n; ++i){dist[i] = graph[0][i];}visited[0] = 1;while(1){edgeType minDist = inf;int minIndex = -1;for(int i=0; i<n; ++i){if(!visited[i] && dist[i] < minDist){minDist = dist[i];minIndex = i;}}if(minIndex == -1){break;}sum += minDist;visited[minIndex] = 1;for(int i=0; i<n; ++i){if(!visited[i] && graph[minIndex][i] < dist[i]){dist[i] = graph[minIndex][i];}}}for(int i=0; i<n; ++i){if(!visited[i]){return -1;}}return sum;
}
edgeType graph[maxn][maxn];#define maxm 100001
int n, m;
int u[maxm], v[maxm], c[maxm];int check(int max){initEdge(n, graph);for(int i=0; i<m; ++i){if(c[i] <= max){addEdge(graph, u[i] - 1, v[i] - 1, c[i]);}}return prim(n, graph) >= 0;}
int main()
{cin >> n >> m;for(int i=0; i<m; ++i){cin >> u[i] >> v[i] >> c[i];}int l = 0, r = 10000;int ans = -1;while(l <= r){int mid = (l + r) / 2;if(check(mid)){r = mid - 1;ans = mid;}else{l = mid + 1;}}cout << n - 1 << ' ' << ans << endl;// 请在此输入您的代码return 0;
}

http://www.dtcms.com/a/338364.html

相关文章:

  • 高等数学 8.5 曲面及其方程
  • Python打卡Day45 预训练模型
  • 【加密PMF】psk-pmk-ptk
  • 【168页PPT】IBM五粮液集团数字化转型项目实施方案建议书(附下载方式)
  • 块体不锈钢上的光栅耦合表面等离子体共振的复现
  • 九联科技UMA223-H低功耗蜂窝模组在物联网设备中的应用与价值分析
  • 信号上升时间Tr不为0的信号反射情况
  • 工具集成强化学习:AI数学推理能力的新跃迁
  • Milvus向量数据库安装步骤
  • DRG/DIP支付改革如何通过大数据分析优化病种分组和权重调整?
  • 知识蒸馏 - 各类概率分布
  • CPP异常
  • 公司无公网IP,如何将内网服务,给外面异地连接使用?远程办公可通过什么访问?
  • 内联汇编(Inline Assembly)是什么?
  • redis命令行学习
  • Linux重要目录结构及目录命令
  • Vue3 中的 provide 和 inject 详解:实现跨组件通信
  • 运用4种填充方法补充缺失数据的案例
  • redis的过期键有哪些删除策略
  • Product Hunt 每日热榜 | 2025-08-18
  • 【跨国数仓迁移最佳实践6】MaxCompute SQL语法及函数功能增强,10万条SQL转写顺利迁移
  • 论往返之迴响:时间之织锦与信息之曼舞
  • [激光原理与应用-294]:理论 - 波动光学 - 衍射光学元件(DOE)
  • 如何生成和安全保存私钥?
  • oracle dg duplicate限速
  • 区块链技术原理(16)-以太坊节点与客户端
  • SpringBoot--JWT
  • WPF 打印报告图片大小的自适应(含完整示例与详解)
  • 初识CNN04——经典网络认识
  • 驱动开发系列64 - glCompileShader实现-GLSL 精度优化pass