最小生成树


Submit solution

Points: 100
Time limit: 1.0s
Memory limit: 80M

Author:
Problem type
Allowed languages
C, C++

最短树问题

题目大意

给你一张带权、连通、无向图,有 (n) 个点、(m) 条边(允许重边和自环)。 请从这些边里挑出 (n-1) 条,把所有点都连起来(形成一棵"支撑树"/生成树),并且让选中边的权值总和最小。把这个最小总权值输出即可。 这棵"最省边权的生成树"就叫最小生成树(MST)。

你需要做什么

从输入的图中,找出最小生成树,输出它的边权和

自环((u=v) 的边)对生成树没用; 重边(同一对点有多条边)可以选其中更便宜的那条,只要能让总和更小。

输入格式

  • 第一行:两个整数 (n, m) —— 点数、边数。
  • 接下来 (m) 行:每行三个整数 (u, v, w),表示一条无向边 ((u,v)),权值为 (w)。

输出格式

  • 输出一行一个整数:最小生成树的边权总和

样例

输入

4 5
1 3 1
1 2 2
2 3 0
3 4 3
1 4 8

输出

4

说明 选边 ((1,3))、((2,3))、((3,4)),总权值 (1+0+3=4),且能连通所有点,这是最小的。

数据范围

  • \(1 \le n \le 2000\)
  • \(1 \le m \le 3000\)
  • 边权 (w) 是区间 \([0, 10^9]\) 内的整数
  • 图保证连通、输入合法
  • 答案可能很大,注意用 64 位整型(C++ 建议 long long

小贴士(思路提示,非必须)

  • KruskalPrim 都能做:

    • Kruskal:把所有边按权值从小到大排序,依次尝试加入,配合并查集避免成环。时间大约 (O(m \log m))。
    • Prim:从任意点出发,每次把"代价最小的外连边"加入,用堆优化为 (O(m \log n))。
  • 忽略自环;重边按权值自然会在排序/挑选时被处理到更优解。

Comments

There are no comments at the moment.