60分求助
查看原帖
60分求助
86624
洛谷Onlinejudge楼主2020/7/28 22:55
#include "bits/stdc++.h"
using namespace std;
#define MAXN 330000

struct EDGE{
	int Next,To;
}E[MAXN*2];
int Head[2*MAXN],Size;
inline void Add(int From,int To){
	E[++Size].Next=Head[From];
	Head[From]=Size;
	E[Size].To=To;
	return;
}

int Fa[MAXN],Tot[MAXN];
int Son[MAXN],Dep[MAXN];
inline void DFS1(int This,int F){
	Fa[This]=F;
	Tot[This]=1;
	int MaxSon=0;
	Dep[This]=Dep[F]+1;
	for(register int i=Head[This];i;i=E[i].Next){
		int To=E[i].To;
		if(To==F)continue;
		DFS1(To,This);
		Tot[This]+=Tot[To];
		if(Tot[To]>MaxSon){
			MaxSon=Tot[To];
			Son[This]=To;
		}
	}
	return;
}

int A[MAXN],InPut[MAXN];
int Count,ID[MAXN],Top[MAXN];
inline void DFS2(int This,int Topf){
	Top[This]=Topf;
	ID[This]=(++Count);
	InPut[Count]=A[This];
	if(Son[This]==0)
		return;
	DFS2(Son[This],Topf);
	for(register int i=Head[This];i;i=E[i].Next){
		int To=E[i].To;
		if(To==Son[This]||To==Fa[This])
			continue;
		DFS2(To,To);
	}
	return; 
}

struct SegmentTree{
	int Lazy,Max,Sum;
	int Left,Right;
}Tree[MAXN*4];

inline int LeftSon(int i){return i<<1;}
inline int RightSon(int i){return i<<1|1;}

inline void Build(int Left,int Right,int i){
	Tree[i].Left=Left;
	Tree[i].Right=Right;
	if(Left==Right){
		Tree[i].Sum=InPut[Left];
		return;
	}
	int Mid=(Left+Right)>>1;
	int L=LeftSon(i),R=RightSon(i);
	Build(Left,Mid,L),Build(Mid+1,Right,R);
	Tree[i].Sum=Tree[L].Sum+Tree[R].Sum;
	return;
}

inline void PushDown(int i){
	if(Tree[i].Lazy==0)
		return;
	int Compare=Tree[i].Lazy;
	int L=LeftSon(i),R=RightSon(i);
	Tree[L].Lazy=max(Tree[L].Lazy,Compare);
	Tree[R].Lazy=max(Tree[R].Lazy,Compare);
	Tree[L].Max=max(Tree[L].Max,Compare);
	Tree[R].Max=max(Tree[R].Max,Compare);
	Tree[i].Lazy=0;
	return;
}

inline int SumSeg(int i,int Left,int Right){
	if(Left>Right)return 0;
	if(Tree[i].Left>Right||Left>Tree[i].Right)
		return 0;
	if(Left<=Tree[i].Left&&Tree[i].Right<=Right)
		return Tree[i].Sum;
	PushDown(i);
	int Sum=0,L=LeftSon(i),R=RightSon(i);
	if(Tree[L].Right>=Left)Sum+=SumSeg(L,Left,Right);
	if(Tree[R].Left<=Right)Sum+=SumSeg(R,Left,Right);
	return Sum;
}

inline int MaxSeg(int i,int W){
	if(Tree[i].Left>W||W>Tree[i].Right)
		return 0;
	if(Tree[i].Left==Tree[i].Right)
		return Tree[i].Max;
	PushDown(i);
	int Max=0;
	int L=LeftSon(i),R=RightSon(i);
	if(Tree[L].Right>=W)Max=max(Max,MaxSeg(L,W));
	if(Tree[R].Left<=W)Max=max(Max,MaxSeg(R,W));
	return Max; 
}

inline void CloSeg(int i,int Left,int Right,int C){
	if(Left>Right)return;
	if(Left>Tree[i].Right||Tree[i].Left>Right)
		return;
	if(Left<=Tree[i].Left&&Tree[i].Right<=Right){
		Tree[i].Lazy=max(Tree[i].Lazy,C);
		Tree[i].Max=max(Tree[i].Max,C);
		return;
	}
	PushDown(i);
	int L=LeftSon(i),R=RightSon(i);
	if(Tree[L].Right>=Left)CloSeg(L,Left,Right,C);
	if(Tree[R].Left<=Right)CloSeg(R,Left,Right,C);
	Tree[i].Max=max(Tree[L].Max,Tree[R].Max);
	return;
}

inline int SumTree(int X,int Y){
	int Sum=0;
	while(Top[X]!=Top[Y]){
		if(Dep[Top[X]]<Dep[Top[Y]])
			swap(X,Y);
		Sum+=SumSeg(1,ID[Top[X]],ID[X]);
		X=Fa[Top[X]];
	}
	if(X==Y)return Sum;
	if(Dep[X]>Dep[Y])
		swap(X,Y);
	Sum+=SumSeg(1,ID[Son[X]],ID[Y]);
	return Sum;
}

int N,M;
inline void Clover(int X,int Y,int Z){
	if(Dep[X]<Dep[Y])
		swap(X,Y);
	CloSeg(1,ID[X]+1,ID[X]+Tot[X]-1,Z);
	if(Top[X]!=Top[Y])
		CloSeg(1,ID[Y]+1,ID[Y]+Tot[Y]-1,Z);
	while(Top[X]!=Top[Y]){
		if(Dep[Top[X]]<Dep[Top[Y]])
			swap(X,Y);
		CloSeg(1,ID[X]+Tot[X],ID[Top[X]]+Tot[Top[X]]-1,Z);
		X=Fa[Top[X]];
	}
	if(X==Y)return;
	if(Dep[X]>Dep[Y])swap(X,Y);
	CloSeg(1,ID[X]+Tot[X],N,Z);
	CloSeg(1,1,ID[X],Z);
	return;
}

inline int Read(void){
	int X=0,Y=1;char C=getchar();
	while(C<'0'||C>'9'){if(C=='-'){Y=-1;}C=getchar();}
	while('0'<=C&&C<='9'){X=X*10+(C-'0');C=getchar();}
	return (X*Y);
}

struct Unsigned{
	int From,To,Num;
	friend bool operator <(Unsigned Num1,Unsigned Num2){
		return Num1.Num>Num2.Num;
	}
}Dis[MAXN];

int X,Y,Z;
int Xi[MAXN],Yi[MAXN],Zi[MAXN];
int main(void){
	N=Read(),M=Read();
	for(register int i=1;i<N;i++){
		Xi[i]=Read(),Yi[i]=Read();
		Add(Xi[i],Yi[i]);
		Add(Yi[i],Xi[i]);
		Zi[i]=Read();
	}
	DFS1(1,0);
	for(register int i=1;i<N;i++){
		if(Dep[Xi[i]]>=Dep[Yi[i]])
			A[Xi[i]]=Zi[i];
		else A[Yi[i]]=Zi[i];
	}
	DFS2(1,1);
	Build(1,N,1);
	for(register int i=1;i<=M;i++){
		X=Read();Dis[i].From=X;
		Y=Read();Dis[i].To=Y;
		Dis[i].Num=SumTree(X,Y);
		Clover(X,Y,Dis[i].Num);
	}
	int Min=1<<30;
	sort(Dis+1,Dis+1+M);
	int Z=Dis[1].Num;
	for(register int i=1;i<=M;i++){
		if(Z!=Dis[i].Num)
			break;
		X=Dis[i].From,Y=Dis[i].To;
		while(Top[X]!=Top[Y]){
			if(Dep[Top[X]]<Dep[Top[Y]])
				swap(X,Y);
			Min=min(Min,max(Z-A[X],MaxSeg(1,ID[X])));
			X=Fa[X];
		}
		if(Dep[X]<Dep[Y])
			swap(X,Y);
		while(X!=Y){
			Min=min(Min,max(Z-A[X],MaxSeg(1,ID[X])));
			X=Fa[X];
		}
	}
	cout<<Min<<endl;
	return 0;
}

测评记录:

这里

2020/7/28 22:55
加载中...