次小生成树,WA 50Pts 求助!!!
查看原帖
次小生成树,WA 50Pts 求助!!!
545986
Jerrycyx楼主2022/7/16 13:08

RT,评测记录\boxed{\texttt{评测记录}}

#include<cstdio>
#include<algorithm>

#define N 100005
#define M 600005

#define LL long long

using namespace std;

LL n,m;
LL ans=0x7fffffffffffffff;

bool choose[M];

struct Allan{
	LL from,to;
	LL next;
	LL val;
}edge[M],tree[M];
LL edge_cnt=0;
LL head[N];
void Add_edge(LL from,LL to,LL value)
{
	edge_cnt++;
	edge[edge_cnt].from=from;
	edge[edge_cnt].to=to;
	edge[edge_cnt].val=value;
	edge[edge_cnt].next=head[from];
	head[from]=edge_cnt;
	return;
}
LL tree_cnt=0;
LL tree_head[N];
void Add_tree(LL from,LL to,LL value)
{
	tree_cnt++;
	tree[tree_cnt].from=from;
	tree[tree_cnt].to=to;
	tree[tree_cnt].val=value;
	tree[tree_cnt].next=tree_head[from];
	tree_head[from]=tree_cnt;
	return;
}

LL Father[N];
void Union_init()
{
	for(LL i=1;i<=n;i++)
		Father[i]=i;
	return;
}
LL Union_get(LL x)
{
	if(Father[x]==x) return x;
	Father[x]=Union_get(Father[x]);
	return Father[x];
}

bool cmp(Allan x,Allan y)
{
	return x.val<y.val;
}
LL min_tree=0;
void Kruskal()
{
	sort(edge+1,edge+m+1,cmp);
	Union_init();
	int cnt=0;
	for(LL i=1;i<=m;i++)
	{
		if(cnt==n-1) break;
		LL x=Union_get(edge[i].from);
		LL y=Union_get(edge[i].to);
		if(x==y) continue;
		Father[x]=y;
		min_tree+=edge[i].val;
		Add_tree(edge[i].from,edge[i].to,edge[i].val);
		Add_tree(edge[i].to,edge[i].from,edge[i].val);
		choose[i]=true;
		cnt++;
	}
	return;
}

LL dep[N];
LL f[N][25];
LL w1[N][25],w2[N][25];
void LCA_init(LL x,LL father)
{
	dep[x]=dep[father]+1;
	for(LL i=0;i<=25;i++)
	{
		/*
		f[x][i+1]=f[f[x][i]][i];
//		w1[x][i+1]=max(w1[x][i],w1[f[x][i]][i]);
		if(w1[x][i]>w1[f[x][i]][i]) w1[x][i+1]=w1[x][i],w2[x][i+1]=w1[f[x][i]][i];
		else w1[x][i+1]=w1[f[x][i]][i],w2[x][i+1]=w1[x][i];
		*/
		
		f[x][i+1]=f[f[x][i]][i];
        w1[x][i+1]=max(w1[x][i],w1[f[x][i]][i]);
        w2[x][i+1]=max(w2[x][i],w2[f[x][i]][i]);
        if(w1[x][i]>w1[f[x][i]][i]) w2[x][i+1]=max(w2[x][i+1],w1[f[x][i]][i]);
        if(w1[x][i]<w1[f[x][i]][i]) w2[x][i+1]=max(w2[x][i+1],w1[x][i]);
        
	}
	for(LL i=tree_head[x];i;i=tree[i].next)
	{
		LL y=tree[i].to;
		if(y==father) continue;
		f[y][0]=x;
		w1[y][0]=tree[i].val;
		LCA_init(y,x);
	}
	return;
}
LL LCA(LL x,LL y)
{
	if(dep[x]<dep[y]) swap(x,y);
	for(LL i=25;i>=0;i--)
	{
		if(dep[f[x][i]]>=dep[y]) x=f[x][i];
		if(x==y) return x;
	}
	for(LL i=25;i>=0;i--)
		if(f[x][i]!=f[y][i])
			x=f[x][i],y=f[y][i];
	return f[x][0];
}

LL Max_value_helper(LL x,LL y,LL value)
{
	LL res=-1;
	for(LL i=25;i>=0;i--)
	{
		if(dep[f[x][i]]>=dep[y])
		{
			if(value!=w1[x][i]) res=max(res,w1[x][i]);
			else res=max(res,w2[x][i]);
			x=f[x][i];
		}
	}
	return res;
}
LL Max_value(LL x,LL y,LL value)
{
	LL p=LCA(x,y);
	LL x_max=Max_value_helper(x,p,value);
	LL y_max=Max_value_helper(y,p,value);
	return max(x_max,y_max);
}
void Haha()
{
	for(LL i=1;i<=m;i++)
	{
		if(choose[i]) continue;
		LL l=Max_value(edge[i].from,edge[i].to,edge[i].val);
		ans=min(ans,min_tree-l+edge[i].val);
	}
	return;
}

int main()
{
	scanf("%lld%lld",&n,&m);
	for(LL i=1;i<=m;i++)
	{
		LL x,y,z;
		scanf("%lld%lld%lld",&x,&y,&z);
		Add_edge(x,y,z);
//		Add_edge(y,x,z);
	}
	Kruskal();
	for(LL i=1;i<=n;i++)
		w2[i][0]=-1;
	LCA_init(1,0);
	Haha();
	printf("%lld\n",ans);
	return 0;
}
2022/7/16 13:08
加载中...