树链抛分怎么处理森林?100分WA求调/_ \
查看原帖
树链抛分怎么处理森林?100分WA求调/_ \
891956
TempestMiku楼主2023/5/8 16:00
#include<bits/stdc++.h>
#define int long long
#define lid root<<1
#define rid root<<1|1
using namespace std;
const int N=100114; 
inline int read(){
	int f(1),x(0);
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
	return f*x;
} 
inline void write(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
	return ;
} 
struct JJ{
	int a,b,w;
	friend bool operator <(const JJ &X,const JJ &Y){
		return X.w>Y.w;
	}
} e[N];
struct tree{
	int l,r,mini;
} t[N<<2];
int n,m,cnt=0,num=0,q,tot=0;
int val[N],head[N<<1],nxt[N<<1],to[N<<1],valu[N<<1];
int f[N],dep[N],siz[N],son[N];
int top[N],rk[N],dfn[N],father[N];
inline void add(int x,int y,int z){
	to[++tot]=y,nxt[tot]=head[x],head[x]=tot,valu[tot]=z;
	return ;
}
inline int find(int x){
	if(x==father[x]) return x;
	else return father[x]=find(father[x]);
}
inline void dfs1(int now,int fa){
	dep[now]=dep[fa]+1;
	siz[now]=1;
	f[now]=fa;
	for(register int i=head[now];i;i=nxt[i]){
		int y=to[i];
		if(y==fa) continue;
		val[y]=valu[i];
		dfs1(y,now);
		siz[now]+=siz[y];
		if(siz[son[now]]<siz[y]){
			son[now]=y;//ヨリカモ 
		}
	}
}
inline void dfs2(int now,int topp){
	top[now]=topp;
	dfn[now]=++num;
	rk[num]=now;
	if(son[now]){
		dfs2(son[now],topp);
	}
	for(register int i=head[now];i;i=nxt[i]){
		int y=to[i];
		if(y==f[now]) continue;
		if(y==son[now]) continue;
		dfs2(y,y);
	}
}
inline void pushup(int root){
	t[root].mini=min(t[lid].mini,t[rid].mini);
	return ;
}
inline void build(int root,int l,int r){
	t[root].l=l,t[root].r=r;
	if(l==r){
		t[root].mini=val[rk[l]];
		return ;
	}
	int mid=(l+r)>>1;
	build(lid,l,mid);
	build(rid,mid+1,r);
	pushup(root);
}
inline int askmin(int root,int l,int r){
	if(l<=t[root].l&&r>=t[root].r){
		return t[root].mini;
	}
	int arc(INT_MAX),mid=(t[root].l+t[root].r)>>1;
	if(l<=mid) arc=min(arc,askmin(lid,l,r));
	if(r>mid) arc=min(arc,askmin(rid,l,r));
	return arc;
}
inline int qmin(int x,int y){
	int arc(INT_MAX);
	while(top[x]!=top[y]){
		if(dfn[top[x]]<dfn[top[y]]) {
			swap(x,y);
		}//xヌウ 
		arc=min(arc,askmin(1,dfn[top[x]],dfn[x]));
		x=f[top[x]];
	}
	if(dfn[x]>dfn[y]){
		swap(x,y);
	}
	arc=min(arc,askmin(1,dfn[x]+1,dfn[y]));
	return arc;
}
signed main(void){
	n=read(),m=read();
	for(register int i=1;i<=n;i++){
		father[i]=i;
	}
	for(register int i=1;i<=m;i++){
		e[i].a=read(),e[i].b=read(),e[i].w=read();
	}
	sort(e+1,e+m+1);
	for(register int i=1;i<=m;i++){
		int x=find(e[i].a),y=find(e[i].b);
		if(x==y) continue;
		father[x]=y;
		add(e[i].a,e[i].b,e[i].w),add(e[i].b,e[i].a,e[i].w); 
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);
	q=read();
	while(q--){
		register int xx=read(),yy=read();
		if(find(xx)!=find(yy)) puts("-1");
		else {
			write(qmin(xx,yy)),putchar('\n');
		} 
	}
	return 0;
}

Hack输入

5 4
1 2 1
1 3 1
2 3 1
4 5 5
1
4 5

输出

5
2023/5/8 16:00
加载中...