按照kruskal的算法流程那样做
按照边权大小排序
只要边的两个点不是都在环内就可以把他们连接起来
然后并查集维护,每个点在不在环内,在哪个连通分量
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 2e5+10;
int pre[maxn],n,m,vis[maxn];
struct edge{
int u,v,w;
bool operator < ( const edge&tmp ) const{ return w>tmp.w; }
}d[maxn];
int find(int x){ return x==pre[x]?x:pre[x]=find(pre[x]); }
int main()
{
while( cin >> n >> m && (n+m) )
{
for(int i=1;i<=n;i++) pre[i] = i;
for(int i=1;i<=m;i++)
{
cin >> d[i].u >> d[i].v >> d[i].w;
d[i].u++, d[i].v++;
}
sort( d+1,d+1+m );
int ans = 0;
for(int i=1;i<=m;i++)
{
int u = d[i].u , v = d[i].v;
int fl = find(u), fr = find(v);
if( fl!=fr )//不在一个连通分量里面
{
if( !vis[fl]&&!vis[fr] ) ans+=d[i].w,pre[fl] = fr;//都不在环内
else if( !vis[fl] || !vis[fr] )//只有一个在环内
ans += d[i].w, pre[fl] = fr, vis[fl] = vis[fr] = 1;
}
else//在一个连通分量里面,可以让他们成环
{
if( !vis[fl] && !vis[fr] )
ans += d[i].w, vis[fl] = vis[fr] = 1;
}
}
cout << ans << endl;
memset( vis,0,sizeof(vis) );
}
return 0;
}