# P4180 【模板】严格次小生成树[BJWC2010]

## 输入输出样例

5 6
1 2 1
1 3 2
2 4 3
3 5 4
3 4 3
4 5 6 

11

## 说明

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<complex>
#define N 400010
#define M 900010
#define INF 214748364700000
#define ll long long
using namespace std;
{
ll x=0,f=1;char s=getchar();
while(s>'9' || s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9' && s>='0'){x=x*10+s-'0';s=getchar();}
return x*f;
}
struct edge{ll to,next,v;}a[N<<1];
struct node{ll x,y,v;}e[M];
bool operator < (node a,node b){return a.v<b.v;}
ll bz[N][21],deep[N],m1[N][21],m2[N][21],f[N],V[N];
ll find(ll x){if(x==f[x])return x;f[x]=find(f[x]);return f[x];}
int n,m;
void dfs(ll x,ll fa)
{
bz[x][0]=fa;
{
ll v=a[i].to;
if(v==fa)continue;
deep[v]=deep[x]+1;
m1[v][0]=a[i].v;
m2[v][0]=-INF;
dfs(v,x);
}
}
void twofold()
{
for(int i=1;i<=20;i++)
for(int j=1;j<=n;j++)
{
bz[j][i]=bz[bz[j][i-1]][i-1];
m1[j][i]=max(m1[j][i-1],m1[bz[j][i-1]][i-1]);
m2[j][i]=max(m2[j][i-1],m2[bz[j][i-1]][i-1]);
if(m1[j][i-1]>m1[bz[j][i-1]][i-1])m2[j][i]=max(m2[j][i],m1[bz[j][i-1]][i-1]);
else if(m1[j][i-1]<m1[bz[j][i-1]][i-1])m2[j][i]=max(m2[j][i],m1[j][i-1]);
}
}
ll lca(ll x,ll y)
{
if(deep[x]<deep[y])swap(x,y);
for(int i=20;i>=0;i--)
if(deep[bz[x][i]]>=deep[y])x=bz[x][i];
if(x==y)return x;
for(int i=20;i>=0;i--)
if(bz[x][i]!=bz[y][i])x=bz[x][i],y=bz[y][i];
return bz[x][0];
}
ll qmax(ll x,ll y,ll d)
{
ll s=-INF;
for(int i=20;i>=0;i--)
if(deep[bz[x][i]]>=deep[y])
{
if(d!=m1[x][i])s=max(s,m1[x][i]);
else s=max(s,m2[x][i]);
x=bz[x][i];
}
return s;
}
int main()
{
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++)
{
ll p=find(e[i].x),q=find(e[i].y);
if(p!=q)
{
t+=e[i].v;f[p]=q;V[i]=1;
}
}
deep[1]=1;m2[1][0]=-INF;
dfs(1,-1);twofold();
ll ans=INF;
for(int i=1;i<=m;i++)
if(!V[i])
{
ll x=e[i].x,y=e[i].y,d=e[i].v,l=lca(x,y),p;
p=t-max(qmax(x,l,d),qmax(y,l,d))+d;
ans=min(ans,p);
}
printf("%lld\n",ans);
return 0;
}

posted @ 2018-04-04 16:46 hyf20010101 阅读(...) 评论(...) 编辑 收藏