不能最大生成树+最大的一条边,但是为什么呢?
if(fx!=fy) 如果两棵树上不是都有回环,那么可以合并,fx挂在fy上,如果其中一个有环,fy标记为有环
if(fx==fy&&!(circle[x]+circle[y]) 如果两棵树上都没有回环,那么x和y还能合并,环数变为1
#include<stdio.h>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int fa[N];
int circle[N];
int n,m;
int ans=0;
struct edge
{
int u,v,w;
bool operator <(const edge &rhs )const
{
return w>rhs.w; //按照从大到小排
}
}a[100010];
void init(int n)
{
for(int i=0;i<n;++i)
{
fa[i]=i;
circle[i]=0;
}
}
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF&&(n+m))
{
init(n);
int cnt=0,sum=0;
for(int i=1;i<=m;++i)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
sort(a+1,a+1+m);
for(int i=1;i<=m;++i)
{
int fx=find(a[i].u);
int fy=find(a[i].v);
if(fx!=fy&&!(circle[fx]==1&&circle[fy]==1)) //两个树的环不能都为1
{
sum+=a[i].w;
fa[fx]=fy;
//circle[fy]=1; //这句话是错的 如果两个都没环,就被强制搞成环了
if((circle[fx]+circle[fy])) circle[fy]=1;
++cnt;
}
else if(fx==fy)
{
if(!(circle[fx]+circle[fy]))
{
sum+=a[i].w;
fa[fx]=fy;
circle[fy]=1;
++cnt;
}
}
if(cnt==n) break; //因为有一个环了,所以总共是n条边
}
printf("%d\n",sum);
}
return 0;
}