1. 程式人生 > 實用技巧 >【樹型結構】51nod 1766 樹上的最遠點對

【樹型結構】51nod 1766 樹上的最遠點對

解法相信大家都理解了,這裡提供一種過載運算子的寫法,感覺很好寫...

#include <bits/stdc++.h>
#define lson (rt<<1)
#define rson (rt<<1|1)
using namespace std;
const int maxn=1e5+10;
int n,m;

struct Edge{
	int from,to,w,nxt;
}e[maxn<<1];

inline int read(){
	int x=0,fopt=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-')fopt=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		x=(x<<3)+(x<<1)+ch-48;
		ch=getchar();
	}
	return x*fopt;
}

int head[maxn],cnt;
inline void add(int u,int v,int w){
	e[++cnt].from=u;
	e[cnt].to=v;
	e[cnt].w=w;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}

int fa[maxn],dep[maxn],siz[maxn],dis[maxn],son[maxn];
void dfs1(int u){
	dep[u]=dep[fa[u]]+1;siz[u]=1;
	for(register int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa[u])continue;
		fa[v]=u;
		dis[v]=dis[u]+e[i].w;
		dfs1(v);
		siz[u]+=siz[v];
		if(!son[u]||siz[v]>siz[son[u]])son[u]=v;
	}
}

int top[maxn];
void dfs2(int u,int t){
	top[u]=t;
	for(register int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa[u])continue;
		dfs2(v,v==son[u]?t:v);
	}
}

inline int lca(int u,int v){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		u=fa[top[u]];
	}
	return dep[u]<dep[v]?u:v;
}

inline int Getdis(int u,int v){
	return dis[u]+dis[v]-2*dis[lca(u,v)];
}

struct Node{
	int l,r;
	friend inline Node operator +(const Node& A,const Node& B){
		int p[4]={A.l,A.r,B.l,B.r};
		int Max=-1;
		Node res;
		for(int i=0;i<4;i++)
			for(int j=i+1;j<4;j++){
				int w=Getdis(p[i],p[j]);
				if(w>Max){
					Max=w;
					res=(Node){p[i],p[j]};
				}
			}
		return res;
	}
}tree[maxn<<2];

inline void pushup(int rt){
	tree[rt]=tree[lson]+tree[rson];
}

inline void Build(int rt,int l,int r){
	if(l==r){
		tree[rt].l=tree[rt].r=l;
		return;
	}
	int mid=(l+r)>>1;
	Build(lson,l,mid);
	Build(rson,mid+1,r);
	pushup(rt);
}

inline Node query(int rt,int l,int r,int s,int t){
	if(s<=l&&t>=r)
		return tree[rt];
	int mid=(l+r)>>1;
	if(t<=mid)return query(lson,l,mid,s,t);
	else if(s>=mid+1)return query(rson,mid+1,r,s,t);
	else return query(lson,l,mid,s,mid)+query(rson,mid+1,r,mid+1,t);
}

inline int Mymax(int a,int b,int c,int d){
	return max(a,max(b,max(c,d)));
}

int main(){
	freopen("D.in","r",stdin);
	freopen("D.out","w",stdout);
	n=read();
	for(register int i=1;i<n;i++){
		int x=read(),y=read(),z=read();
		add(x,y,z);
		add(y,x,z);
	}
	
	dfs1(1);
	dfs2(1,1);
	Build(1,1,n);
	
	m=read();
	while(m--){
		int a=read(),b=read(),c=read(),d=read();
		Node x=query(1,1,n,a,b);
		Node y=query(1,1,n,c,d);
		int ans=Mymax(Getdis(x.l,y.l),Getdis(x.l,y.r),Getdis(x.r,y.l),Getdis(x.r,y.r));
		printf("%d\n",ans);
	}
	return 0;
}