由克鲁斯卡尔算法可以知道,将边排序后一股脑的加入到最小生成树里面,只要没有回路就是最小的生成树。
那么排序过后可能会有一些边是长度相同的,这些边有可能不适用于当前的生成树,但正因为这些长度相同边的存在才导致最小生成树不唯一。
那么将这些无法加进最小生成树,但长度相同的边删除就是结果。
#include <bits/stdc++.h> using namespace std; #define int long long const int maxn = 2e5+10; struct sy { int x; int y; int w; } edge[maxn]; int n, m; int fa[maxn]; bool comp(sy a1, sy a2) { return a1.w<a2.w; } int find(int x) { return fa[x]==0? x:fa[x]=find(fa[x]); } void Merge(int x, int y) { int rootx = find(x); int rooty = find(y); fa[rootx] = rooty; } signed main() { int u, v, w; cin>>n>>m; for (int i=1;i<=m;i++) { cin>>u>>v>>w; edge[i].x = u; edge[i].y = v; edge[i].w = w; } sort(edge+1, edge+1+m, comp); int ans = 0; for (int i=1;i<=m;i++) { int l = i, r = i; while (r<=m&&edge[l].w==edge[r+1].w) r++; for (int j=l;j<=r;j++) { int x = edge[j].x;int y = edge[j].y; int w = edge[j].w; if (find(x)!=find(y)) ans += w; } for (int j=l;j<=r;j++) { int x = edge[j].x;int y = edge[j].y; int w = edge[j].w; if (find(x)!=find(y)) { Merge(x, y); ans -= w; } } } cout<<ans; return 0; }