MnZn求助, WA #12
查看原帖
MnZn求助, WA #12
569516
C6H6楼主2023/4/6 20:34
#include <bits/stdc++.h>
#define int long long

using namespace std;
const long long INF = 4e18;
struct edge{
    int to, nxt; 
    long long w;
}e[200010];
int head[100010], fa[100010][22];//倍增数组
long long ma[100010][22], sma[100010][22];//x 到 fa[x][i] 路径上的最大值和次大值
int Fa[100010], dep[100010];
bool flg[100010];
pair<long long, pair<int, int> > a[300010];
int findf(int x){
    if(x == Fa[x]) return x;
    return Fa[x] = findf(Fa[x]);
}
int cnt = 0;
inline void add(int x, int y, long long z){
    e[++cnt] = {y, head[x], z};
    head[x] = cnt;
}
inline void calc(int x, int i, long long &mm, long long &cm){
    if(i == 0){
        if(ma[x][0] > mm){
            cm = max({mm, cm, sma[x][0]});
            mm = ma[x][0];
        } else cm = max(cm, ma[x][0]);
        return;
    }
    long long tmp = mm;
    if(ma[fa[x][i - 1]][i - 1] == ma[x][i - 1]){
        mm = max(mm, ma[x][i - 1]);
        cm = max({sma[fa[x][i - 1]][i - 1], sma[x][i - 1], cm});
        if(tmp != mm) cm = max(cm, tmp);
    } else if(ma[fa[x][i - 1]][i - 1] > ma[x][i - 1]){
        mm = max(mm, ma[fa[x][i - 1]][i - 1]);
        cm = max({ma[x][i - 1], sma[fa[x][i - 1]][i - 1], cm});
        if(tmp != mm) cm = max(cm, tmp);
    } else if(ma[fa[x][i - 1]][i - 1] < ma[x][i - 1]){
        mm = max(mm, ma[x][i - 1]);
        cm = max({ma[fa[x][i - 1]][i - 1], sma[x][i - 1], cm});
        if(tmp != mm) cm = max(cm, tmp);
    }
}
inline void calc2 (int x, int i, long long &mm, long long &cm) {
    if (ma[x][i] > mm) {
        cm = max ({cm, mm, sma[x][i]});
        mm = ma[x][i];
    }else if (ma[x][i] < mm) cm = max (cm, ma[x][i]);
    if (sma[x][i] > cm) cm = sma[x][i];
}
void dfs(int x){
    for(int i = 1; i <= 19; i++){
        fa[x][i] = fa[fa[x][i - 1]][i - 1];
        calc(x, i, ma[x][i], sma[x][i]);
    }
    for(int i = head[x]; i; i = e[i].nxt){
        int y = e[i].to; long long z = e[i].w;
        if(y == fa[x][0]) continue;
        fa[y][0] = x;
        ma[y][0] = z;
        sma[y][0] = -INF;
        dep[y] = dep[x] + 1;
        dfs(y);
    }
}
inline pair<long long, long long> getma(int x, int y){
    long long ret = -INF, retc = -INF;//最大值, 次大值
    if(dep[x] < dep[y]) swap(x, y);
    for(int i = 19; i >= 0; i--){
        if(dep[fa[x][i]] >= dep[y]){
            calc2(x, i, ret, retc);
            x = fa[x][i];
        }
    }
    if(x == y) return {ret, retc};
    for(int i = 19; i >= 0; i--){
        if(fa[x][i] != fa[y][i]){
            calc2(y, i, ret, retc);
            calc2(x, i, ret, retc);
            y = fa[y][i];
            x = fa[x][i];
        }
    }
    calc2(x, 0, ret, retc);
    calc2(y, 0, ret, retc);
    
    return {ret, retc};
}

signed main(){
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= m; i++) scanf("%lld%lld%lld", &a[i].second.first, &a[i].second.second, &a[i].first);
    iota(Fa + 1, Fa + 1 + n, 1);
    sort(a + 1, a + 1 + m);
    long long sum = 0, ans = INF;
    for(int i = 1; i <= m; i++) {
        int x = a[i].second.first, y = a[i].second.second;
        
        long long z = a[i].first;
        int fx = findf(x), fy = findf(y);
        if(x == y){
            flg[i] = 1;
            continue;
        }
        if(fx == fy) continue;
        add(x, y, z);
        add(y, x, z);
        sum += z;
        Fa[fx] = fy;
        flg[i] = 1;
    }
    
    //cout << sum << endl;
    memset(ma, -0x7f, sizeof(ma));
    memset(sma, -0x7f, sizeof(sma));
    dep[1] = 1;
    dfs(1);
    //cout << sma[4][1] << endl;
    for(int i = 1; i <= m; i++){
        if(flg[i]) continue;
        int x = a[i].second.first, y = a[i].second.second;
        long long z = a[i].first;
        auto w = getma(x, y);
        if(z != w.first) ans = min(ans, sum + z - w.first);
        else ans = min(ans, sum + z - w.second);
    }
    cout << ans << endl;
    return 0;
}
2023/4/6 20:34
加载中...