最大生成树
题目分析:第一次遇见最大生成树的题目,但是它的代码几乎和最小生成树一模一样,唯一不同的就是在排序的时候把最大的边放在前面,那么我们选择的时候就是从最大的边开始,这样一来,遍历完之后,最大生成树就求出来了,刚开始看见这个题目的时候,没看懂最后一句话,说的是dis(u,v)表示路径中的最短的边的边权,但是选择的时候又选择最大的路径,反反复复不是很理解,一看题解,原来是一个最大生成树问题,也就是说在构成通路的基础上,每条边选择最大的边权。
方法一:直接建树
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int pre[maxn];
struct node
{
int a, b, c;
bool operator<(const node x) const
{
return c > x.c;
}
} w[maxn];
int find(int x)
{
if (x != pre[x])
pre[x] = find(pre[x]);
return pre[x];
}
void join(int x, int y)
{
pre[find(x)] = find(y);
}
int main()
{
int n, m;
while (~scanf("%d%d", &n, &m))
{
ll ans = 0;
for (int i = 1; i <= n; ++i)
pre[i] = i;
for (int i = 1; i <= m; ++i)
scanf("%d%d%d", &w[i].a, &w[i].b, &w[i].c);
sort(w + 1, w + m + 1);
for (int i = 1; i <= m; ++i)
if (find(w[i].a) != find(w[i].b))
{
join(w[i].a, w[i].b);
ans += w[i].c;
}
printf("%lld\n", ans);
}
return 0;
}方法二:先判断再加边
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int pre[maxn];
struct node
{
int a, b, c;
bool operator<(const node x) const
{
return c > x.c;
}
} w[maxn];
int find(int x)
{
if (x != pre[x])
pre[x] = find(pre[x]);
return pre[x];
}
int join(int x, int y)
{
int a = find(x);
int b = find(y);
if (a != b)
{
pre[a] = b;
return 1;
}
return 0;
}
int main()
{
int n, m;
while (~scanf("%d%d", &n, &m))
{
ll ans = 0;
for (int i = 1; i <= n; ++i)
pre[i] = i;
for (int i = 1; i <= m; ++i)
scanf("%d%d%d", &w[i].a, &w[i].b, &w[i].c);
sort(w + 1, w + m + 1);
for (int i = 1; i <= m; ++i)
if (join(w[i].a, w[i].b))
{
join(w[i].a, w[i].b);
ans += w[i].c;
}
printf("%lld\n", ans);
}
}
京公网安备 11010502036488号