diff --git "a/problems/0053.\345\257\273\345\256\235.md" "b/problems/0053.\345\257\273\345\256\235.md" index af6ba6c7db523fb51174987737d0cde246d6c6b2..c40203c0e0566397f066b382a748452d3218c54f 100644 --- "a/problems/0053.\345\257\273\345\256\235.md" +++ "b/problems/0053.\345\257\273\345\256\235.md" @@ -3,6 +3,65 @@ [题目链接](https://kamacoder.com/problem.php?id=1053) ## C++ +```C++ +#include +using namespace std; + +// v为节点数量,e为边数量 +int v, e; + +// 最小生成树 +void prim(vector>& adj) { + vector dist(v+1, INT_MAX); // 节点到生成树的距离,初始化为最大距离 + vector used(v+1, 0); // 是否已经加入到生成树中,0表示没加入,1表示加入 + vector pre_node(v+1, 0); // 生成树中节点i的前驱节点,0表示没有前驱 + + // 把序号为1的节点加入生成树,在生成树中的节点到生成树的距离为0 + dist[1] = 0; + + for (int i = 1; i <= v; ++i) { + // 找到生成树距离最小的节点加入生成树 + int closest_node_idx = -1; + for (int j = 1; j <= v; ++j) { + if (!used[j] && (closest_node_idx == -1 || dist[j] < dist[closest_node_idx]) ) { + closest_node_idx = j; + } + } + used[closest_node_idx] = 1; + + // 更新节点到生成树的距离并保存其前驱节点,方便最后计算最短路径 + for (int k = 1; k <= v; ++k) { + if (!used[k] && dist[k] > adj[closest_node_idx][k] ) { + dist[k] = adj[closest_node_idx][k]; + pre_node[k] = closest_node_idx; + } + } + } + + int res = 0; + // 从编号为2的节点开始算最短路径,因为第1个节点没有前驱节点(没有向前的边) + for (int i = 2; i <= v; ++i) { + res += adj[i][pre_node[i]]; + } + printf("%d\n", res); + +} + +int main() { + while (cin>>v>>e) { + int v1, v2, val; + std::vector> adj(v+1, vector(v+1, INT_MAX)); + for (int i = 0; i < e; i++) { + scanf("%d%d%d", &v1, &v2, &val); + adj[v1][v2] = val; + adj[v2][v1] = val; + } + prim(adj); + } + return 0; +} +``` + ## Java