社区讨论

严格次小生成树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 条回复,欢迎继续交流。

正在加载回复...