WA #13 。。
查看原帖
WA #13 。。
1416590
nob_lz楼主2025/2/4 20:35
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
using u64=unsigned long long;

constexpr int inf=1e9;

struct data{
    int u,v,w;
};
struct stu{
    int v,w;
};

struct DSU{
    vector<int> f,siz;
    DSU(){};
    DSU(int n){
        inite(n);
    };
    void inite(int n){
        f.resize(n);
        iota(f.begin(),f.end(),0);
        siz.assign(n,1);
    }
    int find(int x){
        while(f[x]!=x){
            x=f[x]=f[f[x]];
        }
        return x;
    }
    bool merge(int x,int y){
        x=find(x),y=find(y);
        if(x==y) return false;
        else{
            f[y]=x;
            siz[x]+=siz[y];
            return true;
        }
    }
    bool same(int x,int y){
        return (find(x)==find(y));
    }
};

int cmp(data x,data y){
    return x.w<y.w;
}

//严格次大的生成树
//先生成一颗最小生成树 然后枚举选取没有被选中的边 加边,此时会有一个环
//树上倍增LCA维护最大值 以及次大值 然后删除 次大值
 
vector<stu> edge[100005];
void solve(){
    int n,m;
    cin>>n>>m;
    vector<data> a(m+1);
    vector<int> vis(m+1);
    i64 ans=0;
    vector<vector<int>> f(n+1,vector<int>(32)),mx1(n+1,vector<int>(32)),mx2(n+1,vector<int>(32,-inf));
    vector<int> dep(n+1);
    DSU g(n+1);
    for(int i=1;i<=m;++i){
        cin>>a[i].u>>a[i].v>>a[i].w;
    }
    int cnt=0;
    auto kruskal =[&]()->void {
        sort(a.begin()+1,a.end(),cmp);
        for(int i=1;i<=m;++i){
            if(!g.same(a[i].u,a[i].v)){
                g.merge(a[i].u,a[i].v);
                edge[a[i].u].push_back({a[i].v,a[i].w});
                edge[a[i].v].push_back({a[i].u,a[i].w});
                ans+=a[i].w;
                cnt++; 
                vis[i]=1;
                if(cnt>=n-1) return;
            }
        }
    };
    auto dfs=[&](auto& self,int rt,int fno,int w)->void {
        dep[rt]=dep[fno]+1;
        f[rt][0]=fno,mx1[rt][0]=w,mx2[rt][0]=-inf;
        for(int i=1;i<=31;++i){ 
            mx1[rt][i]=max(mx1[f[rt][i-1]][i-1],mx1[rt][i-1]);
            mx2[rt][i]=max(max(mx2[f[rt][i-1]][i-1],mx2[rt][i-1]), mx1[f[rt][i-1]][i-1] == mx1[rt][i-1] ? 0 : min(mx1[f[rt][i-1]][i-1],mx1[rt][i-1]));
            f[rt][i]=f[f[rt][i-1]][i-1];
        }
        for(auto p: edge[rt]){
            if(p.v!=fno){
                self(self,p.v,rt,p.w);
            }
        }
    };
    //返回次大值
    auto LCA=[&](int x,int y,int z)->int {
        int ans=0;
        if(dep[x]>dep[y]) swap(x,y);
        int tem=dep[y]-dep[x];
        for(int i=0;i<=tem && tem;tem>>=1,i++){
            if(tem&1){
                ans= max(ans,mx1[y][i]==z ? mx2[y][i] : mx1[y][i]);
                y=f[y][i];
            }
        }
        if(x==y) return ans;
        for(int i=30;i>=0 && x!=y;--i){
            if(f[x][i] != f[y][i]){
                ans=max(ans,max(mx1[x][i],mx1[y][i]) == z ? max(mx2[x][i],mx2[y][i]) : max(mx1[x][i],mx1[y][i])); 
                x=f[x][i];
                y=f[y][i];
            }
        }
        return  max(ans,max(mx1[x][0],mx1[y][0]) == z ? max(mx2[x][0],mx2[y][0]) : max(mx1[x][0],mx1[y][0])); ;
    };
    kruskal();
    for(int i=1;i<=n;++i){
        if(!dep[i])
        dfs(dfs,i,0,0);
    }
    i64 res=inf;
    i64 tem=0;
    for(int i=1;i<=m;++i){
        if(!vis[i] && a[i].v!=a[i].u){
            tem=LCA(a[i].u,a[i].v,a[i].w);
            res=min(-tem+a[i].w,res); 
            //cout<<tem<<' '<<a[i].w<<'\n';
        }
       
    }
    cout<<ans+res<<'\n';
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    solve();
    return 0;
}

感觉没有哪个爆了啊,为什么错了呢

2025/2/4 20:35
加载中...