84分,求调
查看原帖
84分,求调
649451
wuyuhann123456789楼主2024/8/26 10:51
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
struct edge2
{
	int to,next,w;
}e[200010];
int head[100010];
void add(int from,int to,int w)
{
	static int sum=0;
	e[++sum].to=to;
	e[sum].next=head[from];
	e[sum].w=w;
	head[from]=sum;
}
bool vis[100010];
struct edge
{
	int from,to,w;
}ed[600010];
int Set[100010];
int Find(int x){
	return Set[x]==x ? x : Set[x]=Find(Set[x]);
}
void Union(int a,int b)
{
	Set[Find(a)]=Find(b);
}
bool operator<(edge a,edge b)
{
	return a.w<b.w;
}
ll min_tree;
void Kruskal(int n,int m)
{
	for(int i=1;i<=n;i++)
		Set[i]=i;
	sort(ed+1,ed+1+m);
	for(int i=1;i<=m;i++)
		if(Find(ed[i].from)!=Find(ed[i].to))
		{
//			printf("%d %d\n",i,ed[i].w);
			vis[i]=1;
			Union(ed[i].from,ed[i].to);
			add(ed[i].from,ed[i].to,ed[i].w);
			add(ed[i].to,ed[i].from,ed[i].w);
			min_tree+=1ll*ed[i].w;
		}
}
int l2a1[100010];
void work_log(int n)
{
	for(int i=1;i<=n;i++)
		l2a1[i]=l2a1[i-1]+(1<<l2a1[i-1]==i);
}
int dep[100010],father[100010][30];
int maxs[100010][30],secs[100010][30];
void pre_dfs(int now,int fath)
{
	dep[now]=dep[fath]+1;
	father[now][0]=fath;
	for(int i=1;i<=l2a1[dep[now]];i++)
	{
		father[now][i]=father[father[now][i-1]][i-1];
		if(maxs[now][i-1]==maxs[father[now][i-1]][i-1])
		{
			maxs[now][i]=maxs[now][i-1];
			secs[now][i]=
			max(secs[now][i-1],secs[father[now][i-1]][i-1]);
		}
		else if(maxs[now][i-1]>maxs[father[now][i-1]][i-1])
		{
			maxs[now][i]=maxs[now][i-1];
			secs[now][i]=max(secs[now][i-1],maxs[father[now][i-1]][i-1]);
		}
		else
		{
			maxs[now][i]=maxs[father[now][i-1]][i-1];
			secs[now][i]=max(maxs[now][i-1],secs[father[now][i-1]][i-1]);
		}
	}
	for(int i=head[now];i;i=e[i].next)
		if(fath!=e[i].to)
		{
			maxs[e[i].to][0]=e[i].w;
			secs[e[i].to][0]=-1;
			pre_dfs(e[i].to,now);
		}
}
void lca(int a,int b,int& x,int& y)
{
	if(dep[a]<dep[b])
	{
		lca(b,a,x,y);
		return ;
	}
	x=y=-1;
	while(dep[a]>dep[b])
	{
		if(maxs[a][l2a1[dep[a]-dep[b]]-1]>=x)
		{
			if(maxs[a][l2a1[dep[a]-dep[b]]-1]>x)
				y=x;
			x=maxs[a][l2a1[dep[a]-dep[b]]-1];
			y=max(y,secs[a][l2a1[dep[a]-dep[b]]-1]);
		}
		else
			y=max(y,maxs[a][l2a1[dep[a]-dep[b]]-1]);
		a=father[a][l2a1[dep[a]-dep[b]]-1];
	}
	for(int i=l2a1[dep[a]]-1;i>=0;i--)
	{
		if(father[a][i]!=father[b][i])
		{
			if(maxs[a][i]>=x)
			{
				if(maxs[a][i]>x)
					x=maxs[a][i];
				x=maxs[a][i];
				y=max(y,secs[a][i]);
			}
			else
				y=max(y,maxs[a][i]);
			if(maxs[b][i]>=x)
			{
				if(maxs[b][i]>x)
					y=x;
				x=maxs[b][i];
				y=max(y,secs[b][i]);
			}
			else
				y=max(y,maxs[b][i]);
			a=father[a][i];
			b=father[b][i];
		}
	}
	if(maxs[a][0]>=x)
	{
		if(maxs[a][0]>x)
			y=x;
		x=maxs[a][0];
		y=max(y,secs[a][0]);
	}
	else
		y=max(y,maxs[a][0]);
	if(maxs[b][0]>=x)
	{
		if(maxs[b][0]>x)
			y=x;
		x=maxs[b][0];
		y=max(y,secs[b][0]);
	}
	else
		y=max(y,maxs[b][0]);
}
ll work_sec(int m)
{
	static ll minn=100000000000000;
	for(int i=1;i<=m;i++)
	{
		if(!vis[i])
		{
			int maxx,secc;
			lca(ed[i].from,ed[i].to,maxx,secc);
//			printf("%d %d %d %d %d\n",i,ed[i].from,ed[i].to,maxx,secc);
			ll ans=min_tree+ed[i].w-1ll*maxx;
			if(ans==min_tree&&secc>0)
				ans=min_tree+ed[i].w-1ll*secc;
			if(ans<minn&&ans!=min_tree)
				minn=ans;
		}
	}
	return minn;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	work_log(n);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&ed[i].from,&ed[i].to,&ed[i].w);
		if(ed[i].from==ed[i].to)
			i--,m--;
	}
	Kruskal(n,m);
	pre_dfs(1,0);
//	printf("%lld\n",min_tree);
	printf("%lld",work_sec(m));
	return 0;
}

最后一个测试点RE,求调

2024/8/26 10:51
加载中...