社区讨论

84pts WA#13

P3366【模板】最小生成树参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mhjnslxs
此快照首次捕获于
2025/11/04 05:35
4 个月前
此快照最后确认于
2025/11/04 05:35
4 个月前
查看原帖
CPP
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 5010, maxm = 200010;
int fa[maxn],cnt=0;
void init() { // 初始化
    for (int i = 1; i < maxn; i++) {
        fa[i] = i;
    }
}
int Find(int x) { // 递归计算 x 的根结点
    // 如果 x 是根结点,直接返回
    if (fa[x] == x) {
        return x;
    }
    // x 不是根结点,向上寻找,并进行路径压缩
    return fa[x] = Find(fa[x]);
}

bool judge(int x,int y){
	x=Find(x),y=Find(y);
	if(x!=y)
		return false;
	return true;
}
struct node {
    int x, y, w;
} edge[maxm];
bool cmp(node e1, node e2) {
    // 按照边权从小到大排序
    return e1.w < e2.w;
}
int kruskal(int n, int m) {
    // 并查集初始化
    init();
    // 按边权从小到大排序
    sort(edge,edge+m,cmp);

    int sum = 0;
    for (int i = 0; i < m; i++) {
        int x = Find(edge[i].x);
        int y = Find(edge[i].y);
        if(judge(x,y))continue;
        if (x!=y) {
            // 两个集合合并
            fa[x]=y;
            // 统计边权和
            sum+=edge[i].w;
            //统计边数
            cnt++;
        }
        if(cnt==n-1)break;
    }
    return sum;
}
int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        cin >> edge[i].x >> edge[i].y >> edge[i].w;
    }
    if(cnt>n-1)cout<<"orz";
	else cout<<kruskal(n, m);
    return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...