prim30pts , kruskal79pts,求调

P3366 【模板】最小生成树

___njr___ @ 2023-06-11 17:41:47

#include<bits/stdc++.h>
using namespace std;

namespace prim {
    signed edge[5010][5010];
    signed dis[5010];
    signed st[5010];
    int n;
    inline int prim() {
        int ret = 0; // 返回值(最小代价)
        for (int i = 0 ; i < n; ++i) {/*n-1条边*/
            int t = -1;
            for (int j = 1; j <= n ; ++j)
                if (!~st[j]) //未加入
                    if (t == -1 || st[j] > st[t])
                        t = j;
            if (i && 0x3f3f3f3f == dis[t]) {
                cout << "orz " << endl;
                return -1;
            }
            if (i) ret += dis[t];//选
            st[t] = 1;
            for (int j = 1; j <= n; ++j) {
                dis[j] = min(dis[j], edge[j][t]);
            }
        }
        cout << ret;
        return ret;
    }
    inline void add(int a, int b, int c) {
        edge[a][b] = min(edge[a][b], c);
        edge[b][a] = min(edge[b][a], c);
    }

    void main() {

        memset(dis, 0x3f, sizeof (dis) );
        memset(st, -1, sizeof(st));
        memset(edge, 0x3f, sizeof(edge));
        int m, x, y, z;
        cin >> n >> m;
        while (m-- && cin >> x >> y >> z) add(x, y, z);
        prim();
    }
};
namespace kruskal {
    struct edge {
        int a;
        int b;
        int w;
    } edges[20010];
    int fat[20010];
    int n, m;
    inline void add_mmmmmmmmm(int a, int b, int c, int f) {
        edges[f] = {a, b, c};
    }
    inline void init() {//初始化
        cin >> n >> m;
        int x, y, z;
        for (int i = 0; i < m; ++i)cin >> x >> y >> z, add_mmmmmmmmm(x, y, z, i); //输入
        sort(edges, edges + m, [](edge a, edge b) {
            return a.w < b.w;
        });/*排序*/
        for (int i = 0; i < 20010; ++i)fat[i] = i;//初始化并查集
    }
    inline int find(int x) {
        return fat[x] == x ? x : fat[x] = find(fat[x]);//父亲
    }
//边 = 边(kruskal)
    int cnt = 0; //边数
    inline int add(int a) {//加边(kruskal)
        int x = find(edges[a].a);
        int y = find(edges[a].b);
        int w = edges[a].w;
        if (x ^ y)fat[x] = y, ++cnt;
        return x ^ y ? w : 0 ;
    }
    inline int kruskal() {
        int res = 0;
        for (int i = 0; i < m ; ++i)res += add(i); //加
        if (cnt < n - 1)return -1; //边数不到树
        return res;
    }
    void main() {
        init();
        int t = kruskal();
        if (~t)
            cout << t;
        else
            cout << "orz";
    }
}
int main() {
    kruskal::main();//79pts
    prim::main();//30pts
}

by ___njr___ @ 2023-06-11 17:45:52

kruskal结 数组开小


|