所以为什么第十个点会Re
查看原帖
所以为什么第十个点会Re
233462
Umbrella_Leaf楼主2021/2/4 09:01
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct edge{
	int u,v;
	long long w;
}e[900005];
bool flag[900005];
bool cmp(edge x,edge y){
	return x.w<y.w;
}
int fa[500005];
int get(int x){
	if(x==fa[x])return x;
	else return fa[x]=get(fa[x]);
}
int head[500005],to[800005],Next[800005],tot;
long long val[800005];
void addedge(int x,int y,long long z){Next[++tot]=head[x];to[tot]=y;val[tot]=z;head[x]=tot;}
long long s=0,ans=0;
void Kruskal(){
	int cnt=0;
	for(int i=1;i<=m;i++){
		int x=e[i].u,y=e[i].v;
		if(get(x)!=get(y)){
			fa[get(x)]=get(y);
			s+=e[i].w;
			addedge(x,y,e[i].w);
			addedge(y,x,e[i].w);
			flag[i]=1;
			cnt++;
			if(cnt==n-1)break;
		}
	}
}
int father[500005][30],dep[500005];
long long f[500005][30],g[500005][30];
void dfs(int x,int y){
	for(int i=head[x];i;i=Next[i])
		if(to[i]!=y){
			dep[to[i]]=dep[x]+1;
			father[to[i]][0]=x;
			f[to[i]][0]=val[i];
			for(int j=1;j<=25;j++){
				father[to[i]][j]=father[father[to[i]][j-1]][j-1];
				f[to[i]][j]=max(f[to[i]][j-1],f[father[to[i]][j-1]][j-1]);
			if(f[y][j-1]==f[f[y][j-1]][j-1])g[y][j]=max(g[y][j-1],g[f[y][j-1]][j-1]);
			if(f[y][j-1]<f[f[y][j-1]][j-1])g[y][j]=max(f[y][j-1],g[f[y][j-1]][j-1]);
			if(f[y][j-1]>f[f[y][j-1]][j-1])g[y][j]=max(g[y][j-1],f[f[y][j-1]][j-1]);
			}
			dfs(to[i],x);
		}
}
long long calc(int x,int y,long long z){
	long long max1=-(1ll<<60),max2=-(1ll<<60);
	int k=23;
	if(dep[x]<dep[y])swap(x,y);
	while(dep[x]>dep[y]&&k>=0){
		if(dep[father[x][k]]>=dep[y]){
			if(f[x][k]>max1){
				max2=max1;
				max1=f[x][k];
			}else if(f[x][k]<max1)max2=max(max2,f[x][k]);
			max2=max(max2,g[x][k]);
			x=father[x][k];
		}
		k--;
	}
	if(x==y){
		if(max1<z)return z-max1;
		else return z-max2;
	}
	k=23;
	while(father[x][0]!=father[y][0]&&k>=0){
		if(father[x][k]!=father[y][k]){
			if(f[x][k]>max1){
				max2=max1;
				max1=f[x][k];
			}else if(f[x][k]<max1)max2=max(max2,f[x][k]);
			max2=max(max2,g[x][k]);
			if(f[y][k]>max1){
				max2=max1;
				max1=f[y][k];
			}else if(f[y][k]<max1)max2=max(max2,f[y][k]);
			max2=max(max2,g[y][k]);
			x=father[x][k],y=father[y][k];
		}
		k--;
	}
	if(f[x][0]>max1){
		max2=max1;
		max1=f[x][0];
	}else if(f[x][0]<max1)max2=max(max2,f[x][0]);
	max2=max(max2,g[x][0]);
	if(f[y][0]>max1){
		max2=max1;
		max1=f[y][0];
	}else if(f[y][0]<max1)max2=max(max2,f[y][0]);
	max2=max(max2,g[y][0]);	
	if(max1<z)return z-max1;
	else return z-max2;
}
int main(){
//	freopen("tree.in","r",stdin);
//	freopen("tree.out","w",stdout);
	scanf("%d%d",&n,&m);
	memset(g,-0x7f,sizeof(g));
	for(int i=1;i<=m;i++)scanf("%d%d%lld",&e[i].u,&e[i].v,&e[i].w);
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=n;i++)fa[i]=i;
	Kruskal();
	ans=1ll<<60;
	dep[1]=1;
	dfs(1,0);
	for(int i=1;i<=m;i++)
		if(!flag[i]){
			ans=min(ans,s+calc(e[i].u,e[i].v,e[i].w));
		}
	printf("%lld\n",ans); 
	return 0;
}

这个数组还不够大么

2021/2/4 09:01
加载中...