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

京公网安备 11010502036488号