1 条题解

  • 1
    @ 2026-9-19 17:04:30
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int N = 100010;
    const int M = 300010;
    const int LOG = 18;
    const ll INF = 1e18;
    
    struct Edge {
        int u, v;
        ll w;
        bool inMST;
        bool operator<(const Edge& o) const {
            return w < o.w;
        }
    }e[M];
    
    int fa[N];
    int find(int x) {
        if(fa[x] != x) fa[x] = find(fa[x]);
        return fa[x];
    }
    
    vector<pair<int,ll>> g[N];
    int depth[N];
    int up[N][LOG];
    ll d1[N][LOG]; //最大边权 long long
    ll d2[N][LOG]; //严格次大边权 long long
    
    void dfs(int u, int father, ll val)
    {
        depth[u] = depth[father] + 1;
        up[u][0] = father;
        d1[u][0] = val;
        d2[u][0] = -INF;
        for(int k = 1; k < LOG; k++)
        {
            int mid = up[u][k-1];
            up[u][k] = up[mid][k-1];
            ll a[] = {d1[u][k-1], d2[u][k-1], d1[mid][k-1], d2[mid][k-1]};
            ll mx1 = -INF, mx2 = -INF;
            for(ll x : a)
            {
                if(x > mx1) {
                    mx2 = mx1;
                    mx1 = x;
                } else if(x != mx1 && x > mx2) {
                    mx2 = x;
                }
            }
            d1[u][k] = mx1;
            d2[u][k] = mx2;
        }
        for(auto &p : g[u])
        {
            int v = p.first;
            ll w = p.second;
            if(v != father)
                dfs(v, u, w);
        }
    }
    
    void getMax(int u, int v, ll &mx1, ll &mx2)
    {
        mx1 = -INF, mx2 = -INF;
        if(depth[u] < depth[v]) swap(u, v);
        for(int k = LOG-1; k >= 0; k--)
        {
            if(depth[u] - (1 << k) >= depth[v])
            {
                ll a[] = {mx1, mx2, d1[u][k], d2[u][k]};
                ll nm1 = -INF, nm2 = -INF;
                for(ll x : a)
                {
                    if(x > nm1) nm2 = nm1, nm1 = x;
                    else if(x != nm1 && x > nm2) nm2 = x;
                }
                mx1 = nm1, mx2 = nm2;
                u = up[u][k];
            }
        }
        if(u == v) return;
        for(int k = LOG-1; k >= 0; k--)
        {
            if(up[u][k] != up[v][k])
            {
                ll a[] = {mx1, mx2, d1[u][k], d2[u][k], d1[v][k], d2[v][k]};
                ll nm1 = -INF, nm2 = -INF;
                for(ll x : a)
                {
                    if(x > nm1) nm2 = nm1, nm1 = x;
                    else if(x != nm1 && x > nm2) nm2 = x;
                }
                mx1 = nm1, mx2 = nm2;
                u = up[u][k];
                v = up[v][k];
            }
        }
        ll a[] = {mx1, mx2, d1[u][0], d1[v][0]};
        ll nm1 = -INF, nm2 = -INF;
        for(ll x : a)
        {
            if(x > nm1) nm2 = nm1, nm1 = x;
            else if(x != nm1 && x > nm2) nm2 = x;
        }
        mx1 = nm1, mx2 = nm2;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n, m;
        cin >> n >> m;
        for(int i = 1; i <= m; i++)
        {
            cin >> e[i].u >> e[i].v >> e[i].w;
            e[i].inMST = false;
        }
        sort(e+1, e+1+m);
        for(int i = 1; i <= n; i++) fa[i] = i;
        ll sumMST = 0;
        for(int i = 1; i <= m; i++)
        {
            int u = e[i].u, v = e[i].v;
            ll w = e[i].w;
            int fu = find(u), fv = find(v);
            if(fu != fv)
            {
                fa[fu] = fv;
                sumMST += w;
                e[i].inMST = true;
                g[u].emplace_back(v,w);
                g[v].emplace_back(u,w);
            }
        }
        memset(up,0,sizeof up);
        depth[0] = 0;
        dfs(1,0,-INF);
        ll ans = INF;
        for(int i = 1; i <= m; i++)
        {
            if(e[i].inMST) continue;
            int u = e[i].u, v = e[i].v;
            ll w = e[i].w;
            ll mx1, mx2;
            getMax(u, v, mx1, mx2);
            if(w > mx1)
            {
                ans = min(ans, sumMST + w - mx1);
            }
            else if(w == mx1)
            {
                ans = min(ans, sumMST + w - mx2);
            }
        }
        cout << ans << endl;
        return 0;
    }
    
    
    
    • 1

    信息

    ID
    266
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    10
    已通过
    3
    上传者