1. 克鲁斯卡尔
适合边稠密情况
按边排序从小至大纳入集合
//#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 10;
int father[MAXN] = {0};
int N, M;
struct EDGE
{
int a, b, val;
}edge[MAXN];
bool cmp(EDGE a, EDGE b)
{
return a.val < b.val;
}
void infather(int N)
{
for(int i = 1; i <= N; i++)
father[i] = i;
}
int findfather(int x)
{
if(x == father[x])
return x;
return father[x] = findfather(father[x]);
}
void join(int x, int y)
{
int p = findfather(x), q = findfather(y);
if(p != q)
father[p] = q;
}
bool checkin(int x, int y)
{
int p = findfather(x), q = findfather(y);
if(p == q)
return true;
return false;
}
int main()
{
//ios::sync_with_stdio(false);
//cin.tie(0); cout.tie(0);
cin>>N>>M;
infather(N);
for(int i = 1; i <= M; i++)
cin>>edge[i].a>>edge[i].b>>edge[i].val;
sort(edge + 1, edge + M + 1, cmp);
int ans = 0, sum = 0;
for(int i = 1; i <= M; i++)
{
if( !checkin(edge[i].a, edge[i].b) )
{
join(edge[i].a, edge[i].b);
ans += edge[i].val;
sum++;
}
if(sum == N - 1)
{
cout<<ans<<endl;
goto l1;
}
}
cout<<"orz"<<endl;
l1:
return 0;
}