由克鲁斯卡尔算法可以知道,将边排序后一股脑的加入到最小生成树里面,只要没有回路就是最小的生成树。
那么排序过后可能会有一些边是长度相同的,这些边有可能不适用于当前的生成树,但正因为这些长度相同边的存在才导致最小生成树不唯一。
那么将这些无法加进最小生成树,但长度相同的边删除就是结果。
#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;
}