题目链接:https://www.luogu.org/problemnew/show/P3366
题意理解
给出一个无向图,求出最小生成树。
这就是给用来验板子的
代码
#include <cstring>
#include <iostream>
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>
using namespace std;
/**
* Kruskal算法求MST
* 改自kuangbin大佬的模板,之前也有很多模板是用的他的,对这位前辈大佬表示感谢
*/
const int MAXN = 5010;//最大点数
const int MAXM = 200010;//最大边数
int F[MAXN];//并查集使用
struct Edge {
int u, v, w;
} edge[MAXM];//存储边的信息,包括起点/终点/权值
int tol;//边数,加边前赋值为0
void add_edge(int u, int v, int w) {
edge[tol].u = u;
edge[tol].v = v;
edge[tol++].w = w;
}
bool cmp(Edge a, Edge b) {//排序函数,讲边按照权值从小到大排序
return a.w < b.w;
}
int find(int x) {
if (F[x] == -1) {
return x;
} else {
return F[x] = find(F[x]);
}
}
long long Kruskal(int n) {//传入点数,返回最小生成树的权值,如果不连通返回-1
memset(F, -1, sizeof(F));
sort(edge, edge + tol, cmp);
int cnt = 0;//计算加入的边数
long long ans = 0;
for (int i = 0; i < tol; i++) {
int u = edge[i].u;
int v = edge[i].v;
int w = edge[i].w;
int t1 = find(u);
int t2 = find(v);
if (t1 != t2) {
ans += (long long) w;
F[t1] = t2;
cnt++;
}
if (cnt == n - 1) {
break;
}
}
//不连通
if (cnt < n - 1) {
return -1;
} else {
return ans;
}
}
void read(int &x) {
x = 0;
int f = 1;
char ch = getchar();
while(ch > '9'||ch < '0') {
if(ch == '-') {
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + (int)(ch - 48);
ch = getchar();
}
x = x * f;
}
int main() {
tol = 0;
int n, m;
read(n);
read(m);
for(int i = 0; i < m; i++) {
int x, y, z;
read(x);
read(y);
read(z);
add_edge(x, y, z);
}
long long res = Kruskal(n);
if(res != -1L) {
cout << res;
} else {
cout << "orz";
}
return 0;
}