复习Kruskal(伪暴力建构最小生成树)并查集优化
/*
可以证明当前最短边一定在树中
因此结构体重载小于号排序,从小到大枚举所有边,使其先成为连通块,再整体联通
若最后构建边数小于n-1则无法构建生成树
O(m*logm)->用并查集优化后的结果 并查集连边O(1)
要记忆的知识点:重载小于号和并查集
*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m;
const int N = 1e5+10;
const int M = 2e5+10;
int p[N];
struct Edge
{
int a,b,w;
bool operator <(const Edge&W)const
{
return w<W.w;
}
}edges[M];
int find(int x) // 并查集
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int x,y,z;
scanf("%d%d%d", &x, &y,&z);
edges[i].a=x,edges[i].b=y,edges[i].w=z;
}
sort(edges,edges+m);
int cnt=0;
int res=0;
for(int i=0;i<n;i++) p[i]=i;
for(int i=0;i<m;i++)
{
int a=edges[i].a,b=edges[i].b;
int pa=find(a);
int pb=find(b);
if(pa!=pb)
{
p[pa]=p[pb];
cnt++;
res+=edges[i].w;
}
}
if(cnt>=n-1)
cout<<res<<endl;
else
{
puts("impossible");
}
}