【洛谷】P1669 [USACO04DEC] Bad Cowtractors S 的题解
题解
这是一题最大生成树!!!一直以为是最小生成树,按着板子改的,该半天一直不过qaq
神奇稀疏图
基本思想很简单,就是每次选不属于同一连通分量且边权值最小的 2 2 2 个顶点,将边加入 MST,并将所在的 2 2 2 个连通分量合并,直到只剩一个连通分量
具体算法实现就是这一种思路,首先,先将边按照非降序排列,然后将边合并
∣
V
∣
−
1
\left| V \right| - 1
∣V∣−1 次,取一条边,判断
u
u
u,
v
v
v 是否属于同一连通分量。若不是,则合并
u
u
u,
v
v
v 所在的连通分量,然后输出边
u
u
u,
v
v
v ,最后将 sum
次数加一,sum
则为 MST 的总权值。
代码
#include <bits/stdc++.h>
#define lowbit(x) x & (-x)
#define endl "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
namespace fastIO {
inline int read() {
register int x = 0, f = 1;
register char c = getchar();
while (c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
inline void write(int x) {
if(x < 0) putchar('-'), x = -x;
if(x > 9) write(x / 10);
putchar(x % 10 + '0');
return;
}
}
using namespace fastIO;
struct node{
int a, b, w, nextt;
}s[20005];
int fa[20005], head[20005], ans, n, m, sum, cnt;;
int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
bool cmp (node a, node b) {return a.w > b.w;}
void add(int u, int v, int w) {
s[++ cnt].b = v, s[cnt].a = u, s[cnt].w = w,
s[cnt].nextt = head[u], head[u] = cnt;
}
int main() {
n = read(), m = read();
for(int i = 1; i <= m; i ++) {
s[i].a = read(), s[i].b = read(), s[i].w = read();
add(s[i].a, s[i].b, s[i].w);
}
for (int i = 1; i <= n; i ++) {
fa[i] = i;
}
sort(s + 1, s + m + 1, cmp);
for(int i = 1; i <= m; i ++) {
if (find(s[i].a) != find(s[i].b)) {
sum ++;
fa[find(s[i].b)] = find(s[i].a);
ans += s[i].w;
}
else continue;
if(sum == n - 1) {
write(ans);
return 0;
}
}
write(-1);
return 0;
}