关于倍增LCA90分这件事
查看原帖
关于倍增LCA90分这件事
149219
_mazetorches楼主2020/9/13 17:25

RT,倍增写炸了,求巨佬帮忙!

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
int n,m;
int tot=0,st[300005],zhi[300005],to[300005<<1],nx[300005<<1],fa[300005],ans[300005],vis[300005],dfn[300005],dp[300005][25],shen[300005],ju[300005];
int cha[300005],e[300005],s1[300005],s2[300005],ll[300005];
long long d[300005];
void add(int u,int v,int w){
	to[++tot]=v;
	zhi[tot]=w;
	nx[tot]=st[u];
	st[u]=tot;
}
void dfs(int now,int fa) {
    dp[now][0]=fa;
//    cout<<now<<' '<<fa<<endl;
	dfn[now]=dfn[fa]+1;
    for(int i=1;i<=shen[dfn[now]];i++){
    	dp[now][i]=dp[dp[now][i-1]][i-1];
	}
    for(int i=st[now];i;i=nx[i]){
    	if(to[i]!=fa){
    		d[to[i]]=d[now]+zhi[i];
    		dfs(to[i],now);
		}
	}
}
int LCAohLCA(int u,int v){
	if(dfn[u]<dfn[v]){
		swap(u,v);
	}
    while(dfn[u]>dfn[v]){
    	u=dp[u][shen[dfn[u]-dfn[v]]-1];
	}
    if(u==v) {
    	return u;
	}
    for(int i=shen[dfn[u]]-1;i>=0;i--){
    	if(dp[u][i]!=dp[v][i]){
        	u=dp[u][i];
			v=dp[v][i];
		}
	}
    return dp[u][0];
} 

void dfs2(int u,int fa){
	e[u]=cha[u];
//	if(u==4) cout<<cha[u]<<endl;
	for(int i=st[u];i;i=nx[i]){
    	if(to[i]!=fa){
    		dfs2(to[i],u);
    		ll[to[i]]=zhi[i];
    		e[u]+=e[to[i]];
		}
	}
	return ;
}
bool check(long long q){
	memset(cha,0,sizeof(cha));
	long long maxx=0,he=0;
//	cout<<q<<endl;
	for(long long i=1;i<=m;i++){
		long long p=LCAohLCA(s1[i],s2[i]);
		if(d[s1[i]]+d[s2[i]]-2*d[p]>q){
//			cout<<s1[i]<<' '<<s2[i]<<' '<<p<<' '<<d[s1[i]]+d[s2[i]]-2*d[p]<<'\n';
			he++;
			maxx=max(maxx,d[s1[i]]+d[s2[i]]-2*d[p]);
			cha[p]-=2;
			cha[s1[i]]++;
			cha[s2[i]]++;
		}
	}
//	cout<<maxx<<endl;
	dfs2(1,-1);
	if(he<=0) return 1;
	for(long long i=2;i<=n;i++){
//		cout<<"$$$"<<e[i]<<' '<<he<<' '<<maxx<<' '<<ll[i]<<endl;
		if(e[i]==he&&maxx-ll[i]<=q){
//			cout<<"ohyes"<<ll[i]<<endl<<endl;
			return 1;
		}
	}
//	cout<<"ohno\n\n";
	return 0;
}
int main(){
//	freopen("transport.in","r",stdin);
//	freopen("transport.out","w",stdout);
//	memset(s,0X3f,)
	scanf("%d%d",&n,&m);
	int pd=0;
	int u,v,w;
	for(int i=1;i<=n;i++){
		shen[i]=shen[i-1]+(1<<shen[i-1]==i);
	}
	int maxx=0,he=0;
	for(int i=1;i<n;i++){
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
		add(v,u,w);
		if(u!=v+1&&u!=v-1){
			pd=1;
		}
	}
	dfs(1,0);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&s1[i],&s2[i]);
//		int p=LCAohLCA(u,v);
////		cout<<p<<endl;
//		cha[p]-=2;
////		cha[]--;
//		cha[s1[i]]++;
//		cha[s2[i]]++;
	}
	long long l=-1,r=300000001;
	while(l+1<r){
		long long mid=(l+r)/2;
		if(check(mid)){
//			cout<<"L"<<mid<<endl;
			r=mid;
		}
		else{
//			cout<<"R"<<mid<<endl;
			l=mid;
		}
	}
	printf("%lld",l+1);
	return 0;
}
2020/9/13 17:25
加载中...