算法思路
贪心算法,快速排序,并查集
输入格式
n m(n为点的个数,m为边的条数)
然后m行,每行三个数字a,b,c,a为边的权值,b和c为边的两个顶点的ID。
输出格式
一共n-1行,表示最小生成树的边,每行三个数字a,b,c,其中a为边的权值,b和c为边的两个顶点。
时间复杂度
O(eloge)
代码
//最小生成树 无向图
#include <iostream>
using namespace std;
int n, m; //点的个数,边的个数 点的标号从1到n
int *father; //每个点所对应的树根
int bian[101][3]; //边的权值和始末位置 [L][0]为权值[L][1]和[L][2]为两个端点
//输入部分
int init() {
int i, j;
cin >> n >> m;
father = new int[n + 1];
for (i = 1; i <= m; i++) {
cin >> bian[i][0] >> bian[i][1] >> bian[i][2]; //输入一条边的权值,和两端位置
}
for (i = 1; i <= n; i++) {
father[i] = -1;
}
return 0;
} //快速排序预处理
int quick_sort(int a[][3], int low, int high) {
int i = low, j = high, temp[3];
temp[0] = a[low][0];
temp[1] = a[low][1];
temp[2] = a[low][2];
if (i >= j) return 0;
while (i < j) {
while (j > i && a[j][0] > temp[0]) j--;
if (j > i) {
a[i][0] = a[j][0];
a[i][1] = a[j][1];
a[i++][2] = a[j][2];
}
while (j > i && a[i][0] < temp[0]) i++;
if (j > i) {
a[j][0] = a[i][0];
a[j][1] = a[i][1];
a[j--][2] = a[i][2];
}
}
a[i][1] = temp[1];
a[i][2] = temp[2];
quick_sort(a, low, i - 1);
quick_sort(a, i + 1, high);
return 0;
} //并查集寻找根节点
int find_father(int n) {
if (father[n] == -1)
return n;
else {
return find_father(father[n]);
}
} //算法主体
int work() {
int i, j;
int k1, k2;
for (i = 1; i <= m; i++) {
k1 = find_father(bian[i][1]);
k2 = find_father(bian[i][2]);
if (k1 == k2)
continue;
else {
cout << bian[i][0] << ' ' << bian[i][1] << ' ' << bian[i][2] << endl;
father[k1] = bian[i][2];
}
}
return 0;
}
int main() {
init();
cout << endl;
quick_sort(bian, 1, m);
work();
system("pause");
return 0;
}