28pts Kruskal+Lca求调!
查看原帖
28pts Kruskal+Lca求调!
586417
Bz_nnn楼主2024/8/21 22:09

自认为码风还算良好,望大佬指教
我的提交记录

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 4e5 + 5;
int n, m, cnt, head[N], fa[N], dep[N], up[N][28], fd[N][28], sd[N][28], vis[N];
ll sum, ans;
struct EDGE{ int u, v, w; }edg[N];
struct node{ int to, nxt, dis; }e[N];
void addedge(int f, int g, int w){
    e[++cnt] = node{ g, head[f], w };
    head[f] = cnt;
}
bool cmp(EDGE x, EDGE y){ return x.w < y.w; }
int find_(int x){
    if(fa[x] == x) return x;
    else return fa[x] = find_(fa[x]);
}
void kruskal(){
    int tot = 0;
    for(int i = 0; i <= n; i++) fa[i] = i;
    sort(edg+1, edg+m+1, cmp);
    for(int i = 1; i <= m; i++){
        if(find_(edg[i].u) != find_(edg[i].v)){
            int x = find_(edg[i].u), y = find_(edg[i].v);
            if(x != y) fa[x] = y;
            sum += edg[i].w;
            vis[i] = 1;
            ++tot;
            addedge(edg[i].u, edg[i].v, edg[i].w);
            addedge(edg[i].v, edg[i].u, edg[i].w);
        }
        if(tot == n) break;
    }
}
void dfs(int x, int father){//LCA初始化
    for(int i = head[x]; i; i = e[i].nxt){
        int y = e[i].to, w = e[i].dis;
        if(y == father) continue;
        dep[y] = dep[x] + 1;
        up[y][0] = x;
        fd[y][0] = w;
        dfs(y, x);
    }
}
int lca(int x, int y){
    if(dep[x] < dep[y]) swap(x, y);
    for(int i = 20; i >= 0; i--)
        if(dep[up[x][i]] >= dep[y]) x = up[x][i];
    if(x == y) return x;
    for(int i = 20; i >= 0; i--)
        if(up[x][i] != up[y][i]) x = up[x][i], y = up[y][i];
    return up[x][0];
}
int getmax(int x, int y, int force){//force为要加的边权
    int maxn = 0;
    for(int i = 20; i >= 0; i--){
        if(dep[up[x][i]] >= dep[y]){
            if(force != fd[x][i]) maxn = max(maxn, fd[x][i]);//删的边不为要加的边
            else maxn = max(maxn, sd[x][i]);
            x = up[x][i];
        }
    }
    return maxn;
}
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i++)
        scanf("%d%d%d", &edg[i].u, &edg[i].v, &edg[i].w);
    kruskal();
    dfs(1, 0);
    for(int j = 1; j <= 20; j++){
        for(int i = 1; i <= n; i++){
            up[i][j] = up[up[i][j-1]][j-1];
            if(fd[i][j-1] > fd[up[i][j-1]][j-1]){
                fd[i][j] = fd[i][j-1];
                sd[i][j] = max(sd[i][j-1], fd[up[i][j-1]][j-1]);
            }else if(fd[i][j-1] < fd[up[i][j-1]][j-1]){
                fd[i][j] = fd[up[i][j-1]][j-1];
                sd[i][j] = max(sd[up[i][j-1]][j-1], fd[i][j-1]);
            }else{
                fd[i][j] = fd[i][j-1];
                sd[i][j] = max(sd[i][j-1], sd[up[i][j-1]][j-1]);
            }
        }
    }
    for(int i = 1; i <= m; i++){
        if(vis[i]) continue;
        int u = edg[i].u, v = edg[i].v, w = edg[i].w, x = lca(u, v);
        int maxn = max(getmax(u, x, w), getmax(v, x, w));
        ans = max(ans, sum - maxn + w);
    }
    printf("%lld", ans);
return 0;
}
2024/8/21 22:09
加载中...