线路规划(最小生成树)
题目描述
有n 个村庄之间需要架设通信线路,使得任意两个村庄之间均可通信。两个村庄a, b 间可通信,当且仅当它们之间存在一条通信线路或者存在村庄c 使得a,c 和b,c 间均可通信。给出村庄之间架设通信线路的代价,求出最小的总代价。
输入
第一行包含两个整数n,m,分别表示村庄数量和可以架设通信线路的村庄对数。以下m 行,每行三个整数a,b,c,表示村庄a,b之间架设线路的代价为c(村庄从0 开始编号)。
输出一个整数,最小总代价。
样例输入
3 3
0 1 1
1 2 1
2 0 3
样例输出
2
思路:这道题用克鲁斯卡尔算法,算是一道比较简单的题目,并查集在合并时注意使用按秩合并降低一些时间复杂度,不然会超时,最后答案要使用long long,可能会卡一下,附上AC代码
#include<bits/stdc++.h>
using namespace std;
typedef struct Node
{
int a = 0;
int b = 0;
int dis = 0;
} Node;
int find(int set[], int x)//并查集
{
if(set[x] == x)
return x;
else
return find(set, set[x]);
}
bool cmp(Node a, Node b)//按照距离排序
{
return a.dis < b.dis;
}
int merge(int i, int j, int rank[], int set[])//按秩合并
{
int x = find(set, i); int y = find(set, j);
if(rank[x] <= rank[y])
set[x] = y;
else
set[y] = x;
if(rank[x] == rank[y] && x != y)
rank[y]++;
}
int main()
{
int n = 0; int m = 0;
cin >> n >> m;
Node node[100005];
int set[n] = { 0 };
int rank[n] = { 0 };
for(int i = 1; i <= n; ++i)
{
set[i] = i;
rank[i] = 1;
}
for(int i = 0; i < m; ++i)
{
cin >> node[i].a;
cin >> node[i].b;
cin >> node[i].dis;
}
sort(node, node + m, cmp);
long long res = 0;
for(int i = 0; i < m; ++i)
{
int a = node[i].a; int b = node[i].b; int dis = node[i].dis;
a = find(set, a); b = find(set, b);
if(a != b)
{
merge(a, b, rank, set);
res += dis;
}
}
cout << res << endl;
return 0;
}