问题 A: 线路规划(最小生成树—kruskal—板子题)
题目描述
有n 个村庄之间需要架设通信线路,使得任意两个村庄之间均可通信。两个村庄a, b 间可通信,当且仅当它们之间存在一条通信线路或者存在村庄c 使得a,c 和b,c 间均可通信。给出村庄之间架设通信线路的代价,求出最小的总代价。
输入
第一行包含两个整数n,m,分别表示村庄数量和可以架设通信线路的村庄对数。以下m 行,每行三个整数a,b,c,表示村庄a,b之间架设线路的代价为c(村庄从0 开始编号)。
输出
一个整数,最小总代价。
样例输入 Copy
3 3
0 1 1
1 2 1
2 0 3
样例输出 Copy
2
提示
对于50% 的数据,n<=100,m <=n^2
对于全部数据,1<=n<=10^5; n-1<=m<=10^5,所有代价均在[0, 10^6] 范围内,保证问题有解。
对于全部数据,1<=n<=10^5; n-1<=m<=10^5,所有代价均在[0, 10^6] 范围内,保证问题有解。
思路:最小生成树。
#pragma GCC optimize(3 , "Ofast" , "inline")
#include <bits/stdc++.h>
#define rep(i , a , b) for(register int i=(a);i<=(b);i++)
#define per(i , a , b) for(register int i=(a);i>=(b);i--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int , int> pi;
template<class T>
inline void read (T &x) {
x = 0;
int sign = 1;
char c = getchar ();
while (c < '0' || c > '9') {
if ( c == '-' ) sign = - 1;
c = getchar ();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar ();
}
x = x * sign;
}
const int maxn = 2e5 + 10;
const int inf = int (1e9);
const ll INF = ll (1e18);
const double PI = acos (- 1);
const int mod = 1e9+7;
const double eps = 1e-8;
struct node{
int x,y,z;
}e[maxn];
bool cmp(node A,node B) {
return A.z<B.z;
}
int fa[maxn],n,m;
ll ans;
int FInd(int x) {
if(x==fa[x]) return fa[x];
return fa[x]=FInd (fa[x]);
}
int main () {
read (n);read (m);
rep (i,1,m) {
read (e[i].x);read (e[i].y);read (e[i].z);
e[i].x++;
e[i].y++;
}
sort (e+1,e+1+m,cmp);
rep (i,1,n) fa[i]=i;
rep (i,1,m) {
int x = FInd (e[i].x);
int y = FInd (e[i].y);
if(x==y) continue;
fa[x]=y;
ans+=e[i].z;
}
printf ("%lld\n",ans);
return 0;
}