Kruskal 非严格最小生成树板子求调
  • 板块学术版
  • 楼主tder
  • 当前回复20
  • 已保存回复22
  • 发布时间2024/3/24 09:38
  • 上次更新2024/3/24 17:31:58
查看原帖
Kruskal 非严格最小生成树板子求调
714254
tder楼主2024/3/24 09:38
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5, INF = 1e18;
int n, m, a[N], in[N];
vector<pair<pair<int, int>, int>> g;
map<pair<pair<int, int>, int>, int> mst;
vector<pair<int, int>> f[N];
template<class Tp>
class Ufs {
    private:
        unordered_map<Tp, Tp> f;
        unordered_map<Tp, int> s;
        Tp root(Tp a) {
            if(f[a] == a) return a;
            f[a] = root(f[a]);
            return f[a];
        }
    public:
        void init(Tp *b, Tp *e) {
            int z = 0;
            for(Tp *i = b; i <= e; i++) f[*i] = *i;
        }
        bool same(Tp a, Tp b) {
            Tp p = root(a), q = root(b);
            return p == q;
        }
        void merge(Tp a, Tp b) {
            Tp p = root(a), q = root(b);
            if(p == q) return;
            if(s[p] > s[q]) swap(p, q);
            f[p] = q;
            s[q] += s[p];
        }
};
bool cmp(pair<pair<int, int>, int> x, pair<pair<int, int>, int> y) {
    return x.second < y.second;
}
int Kruskal(int s) {
    int ans = 0;
    Ufs<int> u;
    for(int i = 1; i <= n; i++) a[i] = i;
    u.init(a + 1, a + n + 1);
    sort(g.begin(), g.end(), cmp);
    for(auto i : g) {
        if(u.same(i.first.first, i.first.second)) continue;
        mst[i] = 1;
        f[i.first.first].push_back({i.first.second, i.second}); f[i.first.second].push_back({i.first.first, i.second});
        ans += i.second;
        u.merge(i.first.first, i.first.second);
    }
    if(mst.size() == n - 1) return ans;
    else return -1;
}
int d[N], v[N];
pair<int, int> p[N];
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
void Dijkstra(int s) {
    for(int i = 1; i <= n; i++) d[i] = INF, p[i] = {-1, -1}, v[i] = 0;
    d[s] = 0;
    q.push({d[s], s});
    while(!q.empty()) {
        int i = q.top().second;
        q.pop();
        if(v[i]) continue;
        v[i] = 1;
        for(auto j : f[i]) {
            int k = j.first, w = j.second;
            if(d[k] > d[i] + w) {
                d[k] = d[i] + w, p[k] = {i, w};
                q.push({d[k], k});
            }
        }
    }
}
int work(int u, int v) {
    int r = -INF;
    while(v != u) {
        r = max(r, p[v].second);
        v = p[v].first;
    }
    return r;
}
signed main() {
    cin>>n>>m;
    for(int i = 1; i <= m; i++) {
        int u, v, w; cin>>u>>v>>w;
        g.push_back({{u, v}, w}); g.push_back({{v, u}, w});
    }
    int len = Kruskal(1), ans = INF;
    cout<<len<<" ";
    for(auto i : g) if(mst[i]) {
        int u = i.first.first, v = i.first.second, w = i.second;
        // cout<<"("<<u<<", "<<v<<") "<<w<<endl;
        Dijkstra(u);
        ans = min(ans, len + w - work(u, v));
    }
    cout<<ans<<endl;
    return 0;
}
2024/3/24 09:38
加载中...