LOJ10133

版权声明:发现蒟蒻ff_666,但转载请注明 https://blog.csdn.net/qq_42403731/article/details/82016009

LOJ10133

现在才发现写LOJ10068大材小用了。。
不过想法就是那篇。。

#include<bits/stdc++.h>
#define gt() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++)
#define Up up[x][i-1]
#define LL long long
#define __R register
using namespace std;
static char buf[1000000],*p1=buf,*p2=buf;
const int maxE=(3e5)+5,maxn=(1e5)+5,Log=22,INF=-(2e9);
int n,m,fa[maxn],Pow[Log+5],LoG[maxn];bool vis[maxE];LL Ans=(LL)1<<60,S;
int tot,son[maxn<<1],nxt[maxn<<1],w[maxn<<1],lnk[maxn];
void add_e(int x,int y,int z){son[++tot]=y,w[tot]=z,nxt[tot]=lnk[x],lnk[x]=tot;}
struct Edges{
    int x,y,w;
    bool operator <(const Edges b)const{return w<b.w;}
}E[maxE];
int read(){
    int ret=0;char ch=gt();
    while(ch<'0'||ch>'9') ch=gt();
    while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=gt();
    return ret;
}
int getfa(int x){return fa[x]==x?x:fa[x]=getfa(fa[x]);}
int dep[maxn],up[maxn][Log],val[maxn][Log],vll[maxn][Log];//val最大,vll严格次大 
void DFS(int x,int dad){
    dep[x]=dep[dad]+1,up[x][0]=dad;
    for(__R int i=1;Pow[i]+1<=dep[x];i++){
        up[x][i]=up[Up][i-1];
        if(val[x][i-1]>val[Up][i-1]){
            val[x][i]=val[x][i-1];
            vll[x][i]=(vll[x][i-1]>val[Up][i-1]?vll[x][i-1]:val[Up][i-1]);//此时vll[x][i-1]!=val[x][i-1]且val[Up][i-1]!=val[x][i-1](val[Up][i-1]<val[x][i-1])
        }else{
            val[x][i]=val[Up][i-1];
            if(vll[Up][i-1]>=val[x][i-1]) vll[x][i]=vll[Up][i-1];//vll[Up][i-1]必!=val[Up][i-1] 
              else if(val[x][i-1]!=val[x][i]) vll[x][i]=val[x][i-1];//严格 
                else vll[x][i]=(vll[x][i-1]>vll[Up][i-1]?vll[x][i-1]:vll[Up][i-1]);//vll显然是严格小于的 
        }
    }
    for(__R int j=lnk[x];j;j=nxt[j])if(son[j]!=dad) val[son[j]][0]=w[j],vll[son[j]][0]=INF,DFS(son[j],x);
}
int LCA(int x,int y,int p){
    int D=INF,t;
    if(dep[x]<dep[y]) swap(x,y);
    while(dep[x]>dep[y]){
        if(val[x][t=LoG[dep[x]-dep[y]]-1]!=p) D=val[x][t]>D?val[x][t]:D;else D=vll[x][t]>D?vll[x][t]:D;
        x=up[x][t];
    }
    if(x==y) return D;
    for(__R int k=LoG[dep[x]]-1;k>=0;k--)if(up[x][k]!=up[y][k]){
        if(val[x][k]!=p) D=val[x][k]>D?val[x][k]:D;else D=vll[x][k]>D?vll[x][k]:D;
        if(val[y][k]!=p) D=val[y][k]>D?val[y][k]:D;else D=vll[y][k]>D?vll[y][k]:D;
        x=up[x][k],y=up[y][k];
    }
    __R int k=0;
    if(val[x][k]!=p) D=val[x][k]>D?val[x][k]:D;else D=vll[x][k]>D?vll[x][k]:D;
    if(val[y][k]!=p) D=val[y][k]>D?val[y][k]:D;else D=vll[y][k]>D?vll[y][k]:D;
    return D;
}
int main(){
    n=read(),m=read();
    for(__R int i=1;i<=m;i++) E[i]=(Edges){read(),read(),read()};sort(E+1,E+1+m);
    for(__R int i=0;(Pow[i]=1<<i)<=n;i++);
    for(__R int i=1;i<=n;i++) LoG[i]=LoG[i-1]+(Pow[LoG[i-1]]==i),fa[i]=i;
    for(__R int i=1,fx,fy;i<=m;i++)if((fx=getfa(E[i].x))!=(fy=getfa(E[i].y))){
        fa[fx]=fy,S+=E[i].w,vis[i]=1;
        add_e(E[i].x,E[i].y,E[i].w),add_e(E[i].y,E[i].x,E[i].w);
    }
    DFS(1,0);
    LL now;
    for(__R int i=1;i<=m;i++) if(!vis[i]&&(now=S-LCA(E[i].x,E[i].y,E[i].w)+E[i].w)<Ans) Ans=now;
    printf("%lld\n",Ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42403731/article/details/82016009