const int maxn=1e6;
int n,m;//点数,边数
int u[maxn],v[maxn],w[maxn];//第i条边的两个端点序号和权值
int r[maxn];//排序后第i小的边的序号
int cmp(const int i,const int j){ return w[i]<w[j]; }//间接比较函数
int find(int x){//并查集的find
return p[x]==x?x:p[x]=find(p[x]);
}
int kruskal(){
int ans=0;
for(int i=0;i<n;i++) p[i]=i;//初始化并查集
for(int i=0;i<m;i++) r[i]=i;//初始化边序号
sort(r,r+m,cmp);//给边排序
for(int i=0;i<m;i++){
int e=r[i];
int x=find[u[e]];
int y=find[v[e]];//找出当前边两个端点所在集合编号
if(x!=y){
ans+=w[e];
p[x]=y;//如果在不同集合,合并
}
}
return ans;
}
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6;
int n,m;//点数,边数
int u[maxn],v[maxn],w[maxn];//第i条边的两个端点序号和权值
int r[maxn];//排序后第i小的边的序号
int p[maxn];//i的根结点
int ans,num;
int cmp(const int i,const int j){ return w[i]<w[j]; }//间接比较函数
int find(int x){//并查集的find
return p[x]==x?x:p[x]=find(p[x]);
}
void kruskal(){
ans=0;
for(int i=0;i<n;i++) p[i]=i;//初始化并查集
for(int i=0;i<m;i+