站外最小生成树“板子题”求调

题目总版

Chenaknoip @ 2024-11-12 23:08:58

题目来源:YbtOJ

我写完发现样例过了,交上去发现 WA 0pts。但是该OJ对于未通过的测试点只显示前几行,而我的代码输出前几行的结果是正确的,因此调试 30min 无果求助。

题目大意是给出 m 条边,输出 m 个数,第 i 个数表示表示“前 i 条边连成无向图的最小生成树边权和”乘以 50\% 的结果。图不联通输出 0

样例输入:

3 5
1 2 4
1 3 4
2 3 4
1 3 2
1 2 2

样例输出:

0
4.0
4.0
3.0
2.0

我的想法:跑 m 次 Kruskal 我的代码:

#include <algorithm>
#include <iostream>
using namespace std;
#define int long long

int fa[100010];
int n, m;
struct edge {
    int u, v, w;
};
int l;
edge g[100010];
void add(int u, int v, int w) {
    l++;
    g[l].u = u;
    g[l].v = v;
    g[l].w = w;
}
int findroot(int x) { return fa[x] == x ? x : fa[x] = findroot(fa[x]); }
void Merge(int x, int y) {
    x = findroot(x);
    y = findroot(y);
    fa[x] = y;
}
bool cmp(edge A, edge B) { return A.w < B.w; }
void kruskal() {
    int tot = 0;
    int ans = 0;
    for (int i = 1; i <= m; i++) {
        int xr = findroot(g[i].u), yr = findroot(g[i].v);
        if (xr != yr) {
            Merge(xr, yr);
            tot++;
            ans += g[i].w;
        }
        if (tot >= n - 1) {
            printf("%.1lf\n", (double)ans / 2.0);
            return;
        }
    }
    cout << "0\n";
}
signed main() {
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        add(u, v, w);
        for (int i = 1; i <= n; i++) {
            fa[i] = i;
        }
        sort(g + 1, g + m + 1, cmp);
        kruskal();
    }
    return 0;
}

by Guanlinmsl @ 2024-11-12 23:33:11

感觉像dfs求mst


|