社区讨论
严格次小生成树80分求助#6和#12WA
P4180[BJWC2010] 严格次小生成树参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lo29qnj3
- 此快照首次捕获于
- 2023/10/23 10:18 2 年前
- 此快照最后确认于
- 2023/11/03 10:30 2 年前
CPP
#include<bits/stdc++.h>
using namespace std;
struct line{int u,v,w;}q[300005];
int fa[300005],cnt,m,vis[300005];
struct data{int to,w;};
int n,dep[300005],f[300005][23];
long long ans=0;
int g[300005][23],h[300005][23];
vector<data>head[300005];
bool comp(line x,line y)
{
return x.w<y.w;
}
int findset(int x)
{
return fa[x]==x?x:fa[x]=findset(fa[x]);
}
void updata(int &a,int &b,int c,int d,int e,int f)
{
if(c==e){a=c;b=max(d,f);return ;}
if(c>e) {a=c;b=max(d,e);return ;}
if(c<e) {a=e;b=max(c,f);return ;}
}
void dfs(int u,int fa)
{
for(int i=1;i<=20;i++)
{
if(!f[u][i-1])break;
f[u][i]=f[f[u][i-1]][i-1];
updata(g[u][i],h[u][i],g[u][i-1],h[u][i-1],g[f[u][i-1]][i-1],h[f[u][i-1]][i-1]);
}
for(int i=0;i<head[u].size();i++)
{
int v=head[u][i].to,len=head[u][i].w;
if(v==fa)continue;
g[v][0]=len;h[v][0]=-1;f[v][0]=u;
dep[v]=dep[u]+1;
dfs(v,u);
}
}
void upmax(int &lx,int &ln,int u,int t)
{
if(g[u][t]==lx)
ln=max(ln,h[u][t]);
else
if(g[u][t]<lx)
ln=max(ln,g[u][t]);
else
{
ln=max(lx,h[u][t]);
lx=g[u][t];
}
}
int lca(int u,int v,int w)
{
int lx=-1,ln=-1;
if(dep[u]<dep[v])
swap(u,v);
for(int i=20;i>=0;i--)
if(dep[f[u][i]]>=dep[v])
{
upmax(lx,ln,u,i);
u=f[u][i];
}
if(u==v)
{
if(w==lx)
return w-ln;
return w-lx;
}
for(int i=20;i>=0;i--)
{
if(f[u][i]!=f[v][i])
{
upmax(lx,ln,u,i);
upmax(ln,lx,v,i);
u=f[u][i];
v=f[v][i];
}
}
upmax(lx,ln,u,0);
upmax(lx,ln,v,0);
if(w==lx)
return w-ln;
return w-lx;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&q[i].u,&q[i].v,&q[i].w);
sort(q+1,q+m+1,comp);
for(int i=1;i<=n;i++)
fa[i]=i;
for(int i=1;i<=m;i++)
{
int u=q[i].u,v=q[i].v;
if(findset(u)==findset(v))
continue;
fa[findset(u)]=findset(v);
vis[i]=1;
head[u].push_back((data){v,q[i].w});
head[v].push_back((data){u,q[i].w});
ans+=q[i].w;cnt++;
if(cnt==n-1)
break;
}
dep[1]=1;dfs(1,0);int z=2e9,a;
for(int i=1;i<=m;i++)
if(!vis[i]&&q[i].u!=q[i].v)
z=min(z,lca(q[i].u,q[i].v,q[i].w)),a=1;
if(a==1)
printf("%lld",ans+z);
else printf("%lld",ans);
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...