先存后排序
#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#define MAXN 100100
using namespace std;
struct Edge
{
int point1;
int point2;
int weight;
};
bool cmp(Edge &x, Edge &y)
{
return x.weight < y.weight;
}
int pre[MAXN];
vector <Edge> vec;
int find(int x)
{//并查集
int root = x;
while (pre[root] != root)
root = pre[root];//找根
int t = x;
while (pre[t] != root)
{//路径压缩
int temp = pre[t];
pre[t] = root;
t = temp;
}
return root;
}
int main(void)
{
int n, m;
int min_sum = 0;
scanf("%d%d", &n, &m);//n是点数,m是边数
if (m)
{
for (int i = 0; i < n; i++)
pre[i] = i;//初始化并查集
for (int i = 0; i < m; i++)
{//输入每条边的两个顶点及其权重
Edge temp;
scanf("%d%d%d", &temp.point1, &temp.point2, &temp.weight);
vec.push_back(temp);
}
sort(vec.begin(), vec.end(), cmp);//按权重对边进行排序
pre[vec[0].point1] = pre[vec[0].point2];//第一条边绝对在,所以我先把他们连起来
min_sum += vec[0].weight;//加上权重
int coun = 1;//此时有了一条已经链接好的边
for (int i = 1; i < m; i++)
{//最多只有m条边
int fx = find(vec[i].point1);
int fy = find(vec[i].point2);
if (fx != fy)
{//如果这条边的两个顶点所在集合不相同就合并
coun++;//成功合并后就多了一条边
min_sum += vec[i].weight;
pre[fx] = fy;//合并
if (coun == n - 1)
break;//krusal有n-1条边
}
}
printf("%d\n", min_sum);
}
else
printf("0\n");
//system("pause");
return 0;
}
直接存入一个堆(优先队列)中
#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <queue>
#define MAXN 100100
using namespace std;
struct Edge
{
int point1;
int point2;
int weight;
};
bool cmp(Edge &x, Edge &y)
{
return x.weight < y.weight;
}
bool operator < (const Edge& a, const Edge& b)
{
return a.weight > b.weight;
}
int pre[MAXN];
priority_queue <Edge> pque;
int find(int x)
{//并查集
int root = x;
while (pre[root] != root)
root = pre[root];//找根
int t = x;
while (pre[t] != root)
{//路径压缩
int temp = pre[t];
pre[t] = root;
t = temp;
}
return root;
}
int main(void)
{
int n, m;
int min_sum = 0;
scanf("%d%d", &n, &m);//n是点数,m是边数
if (m)
{
for (int i = 0; i < n; i++)
pre[i] = i;//初始化并查集
for (int i = 0; i < m; i++)
{//输入每条边的两个顶点及其权重
Edge temp;
scanf("%d%d%d", &temp.point1, &temp.point2, &temp.weight);
pque.push(temp);
}
pre[pque.top().point1] = pre[pque.top().point2];//第一条边绝对在,所以我先把他们连起来
min_sum += pque.top().weight;//加上权重
pque.pop();
int coun = 1;//此时有了一条已经链接好的边
while (!pque.empty())
{//最多只有m条边
int fx = find(pque.top().point1);
int fy = find(pque.top().point2);
if (fx != fy)
{//如果这条边的两个顶点所在集合不相同就合并
coun++;//成功合并后就多了一条边
min_sum += pque.top().weight;
pre[fx] = fy;//合并
if (coun == n - 1)
break;//krusal有n-1条边
}
pque.pop();
}
printf("%d\n", min_sum);
}
else
printf("0\n");
//system("pause");
return 0;
}