数据水了?
查看原帖
数据水了?
141393
Dyd本人楼主2021/4/9 17:27

在洛谷上过了的代码

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const ll N=3e5+5,M=9e5+5,INF=1e15;
ll n,m,ans=0,d[N],f[N][30],D=18,ans2=INF;
ll fa[N];
ll mi[30],maxn[N][30],tmax[N][30];
bool v[M];
struct edge{
	ll x,y,z;
	ll ne;
}g[N<<1],e[N];
ll idx=0,h[N];
void double_add(ll x,ll y,ll z){
	g[++idx].x=x,g[idx].y=y,g[idx].z=z,g[idx].ne=h[x],h[x]=idx;
	g[++idx].x=y,g[idx].y=x,g[idx].z=z,g[idx].ne=h[y],h[y]=idx;
	return ;
}
bool cmp(edge x,edge y){
	return x.z<y.z;
}
ll read(){
	ll x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
	return  x;
}
ll Get(ll x){
	if(fa[x]==x) return x;
	return fa[x]=Get(fa[x]);
}
void dfs(ll x,ll f_,ll dep){		//倍增预处理
	d[x]=dep;
	for(ll i=1;;i++){
		if(d[x]-mi[i]<0) break;
		f[x][i]=f[f[x][i-1]][i-1];
		ll k=f[x][i-1];
		maxn[x][i]=max(maxn[x][i-1],maxn[k][i-1]);
		if(maxn[x][i-1]==maxn[k][i - 1])
			tmax[x][i]=max(tmax[x][i - 1],tmax[k][i - 1]);
		else
			tmax[x][i]=max(min(maxn[x][i-1],maxn[k][i-1]),
			max(tmax[x][i-1],tmax[k][i-1]));
	}
	for(ll i=h[x];i!=-1;i=g[i].ne){
		ll y=g[i].y;
		if(y!=f_){
			f[y][0]=x;
			maxn[y][0]=g[i].z;
			tmax[y][0]=-1;
			dfs(y,x,dep+1);
		}
	}
	return ;
}
ll LCA(ll x,ll y){
	if(d[x]<d[y]) swap(x,y);
	ll k=d[x]-d[y];
	for(ll i=0;i<=D;++i)
		if(k>>i&1) x=f[x][i];
	if(x==y) return x;
	for(ll i=D;i>=0;--i)
		if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
	return f[x][0];
}
void Work(ll x,ll y,ll z){
	ll m1=0,m2=0,k=d[x]-d[y];
	for(ll i=0;i<=D;++i){
		if(k>>i&1){
			m2=max(m2,tmax[x][i]);
			if(maxn[x][i]>m1){
				m2=max(m1,m2);
				m1=maxn[x][i];
			}
		} 
	}
	if(m1==z) ans2=min(ans2,z-m2);
	else ans2=min(ans2,z-m1);
	return ; 
}
void Kru(){
	sort(e+1,e+1+m,cmp);
	for(ll i=1;i<=n;++i) fa[i]=i,v[i]=false;
	ll js=0;
	for(ll i=1;js<n-1;++i){
		ll x=Get(e[i].x);
		ll y=Get(e[i].y);
		if(x==y) continue;
		fa[x]=y;
		js++;
		ans+=e[i].z;
		v[i]=true;
		double_add(e[i].x,e[i].y,e[i].z);
	}
	return ;
}
int main(){
	n=read();m=read();
	for(ll i=1;i<=n;++i) h[i]=-1;
	mi[0]=1;
	for(ll i=1;i<=D;++i) mi[i]=mi[i-1]<<1;
	for(ll i=1;i<=m;++i){
		e[i].x=read();e[i].y=read();e[i].z=read();
	}
	Kru();
	dfs(1,0,1);
	for(ll i=1;i<=m;++i){
		if(!v[i]){
			ll x=e[i].x,y=e[i].y;
			ll l=LCA(x,y);
			Work(x,l,e[i].z);
			Work(y,l,e[i].z);
		}
	}
	printf("%d",ans+ans2);
	return 0;
}                           

交loj上WA一个点 )

求大佬解惑

2021/4/9 17:27
加载中...