//按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路
//每次选边权最小的边(不成环--用并查集)
const int N = 1e5 + 10;
int n, m;
int q[N];
struct edge {
int a, b, w;
}edges[2 * N];//存边
class cmp {
public:
bool operator ()(const edge e, const edge w)const
{
return e.w < w.w;
}
};
int find(int x)
{
if (q[x] == x)return x;
return q[x] = find(q[x]);
}
bool merge(int x, int y)
{
int tx = find(x), ty = find(y);
if (tx == ty)return false;
else
{
q[tx] = ty;
return true;
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i < N; i++)q[i] = i;//并查集初始化
for (int i = 0; i < m; i++)
{
int a, b, w;
cin >> a >> b >> w;
edges[i] = { a, b, w };
}
sort(edges, edges + m, cmp());//按边权排序
int res = 0, cnt = 0;
for (int i = 0; i < m; i++)
{
int a = edges[i].a, b = edges[i].b, w = edges[i].w;//
//用并查集将最小的边加入集合
if (merge(a, b))res += w, cnt++;
}
//n个点 n - 1 条边 小于说明没有最小生成树
if (cnt < n - 1)cout << "No";
else cout << res;
return 0;
}
克鲁斯卡尔
最新推荐文章于 2025-03-18 19:45:24 发布