蒟蒻求助WA#11
查看原帖
蒟蒻求助WA#11
592662
zhaoxibo楼主2022/7/13 22:25

求大佬指点

LCA

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int M=300010;
const int N=100010;
typedef long long ll;
struct sd{
	int from;
	int to;
	ll value;
}a[M];
int n,m;
int p[N],fa[N];bool flag[M];
vector<int>edge[M];
int shen[N];bool vs[N];
int G[N][35][2];
int F[N][35];
inline int get(){
	char c;
	int sign=1;
	while((c=getchar())<'0'||c>'9') if(c=='-') sign=-1;
	int res=c-'0';
	while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
	return res*sign;
}
int cmp(const sd &A,const sd &B){
	if(A.value<B.value) return 1;
	else return 0;
}
int findth(int x)
{
	if(p[x]==x)
		return x;
	else
		return p[x]=findth(p[x]);
}
void unionn(int x,int y)
{
	int x1=findth(x);
	int y1=findth(y);
	if(x1!=y1)
	p[x1]=y1;
}
void dfs(int x){
	vs[x]=true;
	for(int i=1;i<=30;i++){
		F[x][i]=F[F[x][i-1]][i-1];
		G[x][i][0]=max(G[x][i-1][0],G[F[x][i-1]][i-1][0]);
		if(G[x][i-1][0]==G[F[x][i-1]][i-1][0])
			G[x][i][1]=max(G[x][i-1][1],G[F[x][i-1]][i-1][1]);
		else if(G[x][i-1][0]<G[F[x][i-1]][i-1][0])
			G[x][i][1]=max(G[x][i-1][0],G[F[x][i-1]][i-1][1]);
		else
			G[x][i][1]=max(G[x][i-1][1],G[F[x][i-1]][i-1][0]);
	}
	for(int i=0;i<edge[x].size();i++){
		int y=a[edge[x][i]].to+a[edge[x][i]].from-x;
		if(vs[y]) continue;
		shen[y]=shen[x]+1;
		F[y][0]=x;
		G[y][0][0]=a[edge[x][i]].value;
		G[y][0][1]=-1e9;
		dfs(y);
	}
}
int lca(int x,int y){
	if(shen[x]<shen[y]) swap(x,y);
	if(shen[x]!=shen[y]){
		for(int i=30;i>=0;i--){
			int ju=shen[x]-shen[y];
			if(ju&(1<<i)){
				x=F[x][i];
			}
		}
	}
	if(x==y) return x;
	for(int i=30;i>=0;i--){
		if(F[x][i]!=F[y][i]){
			x=F[x][i];
			y=F[y][i];
		}
	}
	return F[x][0];
}
int work(int x,int y,int z){
	if(x==y) return 0;
	int LCA=lca(x,y);
	int Max=0,Cimax=0;
	for(int i=30;i>=0;i--){
		int xju=shen[x]-shen[LCA];
		int yju=shen[y]-shen[LCA];
		if(xju&(1<<i)){
			int lin1=G[x][i][0];
			int lin2=G[x][i][1];
			if(lin1>Max){Cimax=Max;Max=lin1;}
			if(lin1<Max&&lin1>Cimax) Cimax=lin1;
			if(lin2>Cimax&&lin2<Max) Cimax=lin2;
			x=F[x][i];
		}
		if(yju&(1<<i)){
			int lin1=G[y][i][0];
			int lin2=G[y][i][1];
			if(lin1>Max){Cimax=Max;Max=lin1;}
			if(lin1<Max&&lin1>Cimax) Cimax=lin1;
			if(lin2>Cimax&&lin2<Max) Cimax=lin2;
			y=F[y][i];
		}
	}
	if(Max==z) return z-Cimax;
	else return z-Max;
}
int main()
{
	n=get();m=get();
	for(int i=1;i<=m;i++){
		int x,y;ll z;
		x=get();y=get();z=get();
		a[i].from=x;a[i].to=y;a[i].value=z;
	}
	sort(a+1,a+m+1,cmp);
	ll ans=0;
	ll mxrede=-1;
	int ls=n-1;
	for(int i=1;i<=n;i++)
		p[i]=i;
	for(int i=1;i<=m&&ls;i++){
		if(findth(a[i].from)!=findth(a[i].to)){
			flag[i]=true;
			ans+=a[i].value;
			unionn(a[i].to,a[i].from);
			mxrede=max(mxrede,a[i].value);
			ls--;
		}
	}
	for(int i=1;i<=m;i++){
		if(flag[i]){
			edge[a[i].from].push_back(i);
			edge[a[i].to].push_back(i);
		}
	}
	shen[1]=1;
	dfs(1);
	int res=2147483647;
	for(int i=1;i<=m;i++){
		if(!flag[i]){
			if(a[i].value-mxrede>res) break;
			int lin=work(a[i].from,a[i].to,a[i].value);
			res=min(res,lin);
			if(res==0) res=1e9;
		}
	}
	printf("%lld\n",ans+(res==1e9?0:res));
	return 0;
}
2022/7/13 22:25
加载中...