求助LCA,我的程序过了讨论区我能找到的所有HACK数据但只有40pt
查看原帖
求助LCA,我的程序过了讨论区我能找到的所有HACK数据但只有40pt
256970
xie_lzh楼主2022/5/13 20:53

RT

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define ll long long
int read()
{
	int r=0,f=1;
	char c=getchar();
	while(!isdigit(c))
	{
		if(c=='-')f=0;
		c=getchar();
	}
	while(isdigit(c))
	{
		r=(r<<1)+(r<<3)+c-48;
		c=getchar();
	}
	return f?r:-r;
}

const int N=1e5+5,M=3e5+5;
int n,m,ans[N],tot,fa[N],cnt;
int to[M<<1],nxt[M<<1],head[N],val[M<<1],cnt1;
int dep[N],f[N][20],Max[N][20],sMax[N][20];
int Min_tree,sMin_tree;
bool vis[N];
struct edg
{
	int u,v,w;
}b[M];
bool operator == (edg x,edg y)
{
	return x.u==y.u&&x.v==y.v&&x.w==y.w;
} 
struct node
{
	int l,r,val;
}a[M];
bool cmp(node x,node y ){return x.val<y.val;}
bool cmp2(edg x,edg y)
{
	if(x.w==y.w)
	{
		if(x.u==y.u) return x.v<y.v;
		return x.u<y.u;
	}
	return x.w<y.w;
}
int find(int x)
{
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}
void add(int u,int v,int w)
{
	to[++cnt1]=v;
	nxt[cnt1]=head[u];
	val[cnt1]=w;
	head[u]=cnt1;
} 
void dfs(int now,int ff,int prev)
{
	f[now][0]=ff;
	Max[now][0]=prev;
	dep[now]=dep[ff]+1; 
	for(int i=1;i<=19;i++)
	{
		f[now][i]=f[f[now][i-1]][i-1];
		if(Max[now][i-1]!=Max[f[now][i-1]][i-1])
			sMax[now][i]=min(Max[now][i-1],Max[f[now][i-1]][i-1]);
//		sMax[now][i]=max(max(min(Max[now][i-1],Max[f[now][i-1]][i-1]),sMax[now][i-1]),sMax[f[now][i-1]][i-1]);
		Max[now][i]=max(Max[now][i],Max[f[now][i-1]][i-1]);
		sMax[now][i]=max(sMax[now][i],max(sMax[now][i-1],sMax[f[now][i-1]][i-1]));
	}
	for(int i=head[now];i;i=nxt[i])
	{
		int v=to[i];
		if(v==ff) continue;
		dfs(v,now,val[i]);
	}
}

int get_val(int pos)
{
	int x=a[pos].l,y=a[pos].r,w=a[pos].val;
	int Ma=-1,sMa=-1;
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=19;i>=0;i--)
		if(dep[f[x][i]]>=dep[y])
		{
//			Ma=max(Ma,Max[x][i]);
//			sMa=max(sMa,sMax[x][i]);
			if(Max[x][i]>Ma)
			{
				sMa=max(sMa,Ma);
				Ma=Max[x][i];
			}
			if(Max[x][i]<Ma)
				sMa=max(sMa,Max[x][i]);
			sMa=max(sMa,sMax[x][i]);
			x=f[x][i];
		}
	if(x==y)
	{
		if(w==Ma) return sMa;
		return Ma;
	}
	for(int i=19;i>=0;i--)
		if(f[x][i]!=f[y][i])
		{
//			Ma=max(Ma,max(Max[x][i],Max[y][i]));
			sMa=max(sMa,max(sMax[x][i],sMax[y][i]));
			if(Max[x][i]>Ma)
			{
				sMa=max(sMa,Ma);
				Ma=Max[x][i];
			}
			if(Max[x][i]<Ma)
				sMa=max(sMa,Max[x][i]);
			if(Max[y][i]>Ma)
			{
				sMa=max(sMa,Ma);
				Ma=Max[y][i];
			}
			if(Max[y][i]<Ma)
				sMa=max(sMa,Max[y][i]);
			x=f[x][i]; y=f[y][i];
		}
	if(Max[x][0]>Ma)
	{
		sMa=max(sMa,Ma);
		Ma=Max[x][0];
	}
	if(Max[x][0]<Ma)
		sMa=max(sMa,Max[x][0]);
	if(Max[y][0]>Ma)
	{
		sMa=max(sMa,Ma);
		Ma=Max[y][0];
	}
	if(Max[y][0]<Ma)
		sMa=max(sMa,Max[y][0]);
	if(w==Ma) return sMa;
	return Ma;
}
signed main()
{
	n=read(); m=read();
	for(int i=1;i<=n;i++)	
		fa[i]=i;
	for(int i=1;i<=m;i++)
		b[i]=edg{read(),read(),read()};
//	sort(b+1,b+1+m,cmp2);
	for(int i=1;i<=m;i++)
	{
		if(b[i].u==b[i].v) continue;
		a[++cnt]=node{b[i].u,b[i].v,b[i].w};
	}
	sort(a+1,a+1+cnt,cmp);
	for(int i=1;i<=cnt;i++)
	{
		int xx=find(a[i].l),yy=find(a[i].r);
		if(xx==yy) continue;
		add(a[i].l,a[i].r,a[i].val);
		add(a[i].r,a[i].l,a[i].val);
		fa[xx]=yy;
		ans[++tot]=i;
		vis[i]=1;
		Min_tree+=a[i].val;
		if(tot==n-1) break;
	}
	memset(sMax,-1,sizeof sMax);
	dfs(1,0,0);
	sMin_tree=0x7f7f7f7f7f7f7f7f;
	for(int i=1;i<=cnt;i++)
	{
		if(vis[i]) continue;
		int npos=get_val(i);
		if(npos==-1) continue;
		sMin_tree=min(sMin_tree,Min_tree-npos+a[i].val);
	}
	cout<<sMin_tree;
}
/*
4 4 
1 2 1
2 3 2
3 4 1
2 4 2 
*/
2022/5/13 20:53
加载中...