萌新刚学的树剖又炸了,看了一天了还没看出来,头发都要掉光了!
查看原帖
萌新刚学的树剖又炸了,看了一天了还没看出来,头发都要掉光了!
178131
郁逸丶楼主2020/9/29 21:03
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define ls p<<1
#define rs p<<1|1
using namespace std;
const int N = 1e6+5;
int n,m,q,tot,head[N],b[N];
inline int read()
{
	register int x=0,f=1;register char ch=getchar();
	while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
} 
struct node{int u,v,d,next;}a[N];
struct tree{int l,r,size,pre,minn;}t[N];
struct edge{int x,y,z;}tree[N];
int fa[N];
void add(int u,int v,int d)
{
	tot++;
	a[tot].u=u;
	a[tot].v=v;
	a[tot].d=d;
	a[tot].next=head[u];
	head[u]=tot;
}
int find(int x)
{
	if(fa[x]!=x) return fa[x]=find(fa[x]); 
}
void kruskal()
{
	int f1,f2,k=0;
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=i;i<=m;i++)
	{
		f1=find(tree[i].x);
		f2=find(tree[i].y);
		if(f1!=f2)
		{
			fa[f1]=f2;
			add(tree[i].x,tree[i].y,tree[i].z);
			add(tree[i].y,tree[i].x,tree[i].z);
			k++;
			if(k==n-1)break;
		}
	}
}
bool cmp(const edge &x,const edge &y){return x.z>y.z;}
int deep[N],f[N],size[N],son[N];
void dfs1(int u,int fa,int dep)
{
	deep[u]=dep;
	f[u]=fa;
	size[u]=1;
	for(int i=head[u];i;i=a[i].next)
	{
		int v=a[i].v;
		if(v==fa)continue;
		b[v]=a[i].d;
		dfs1(v,u,dep+1);
		size[u]+=size[v];
		if(size[v]>size[son[u]]) son[u]=v;
	}
} 
int top[N],id[N],cnt,rk[N];
void dfs2(int u,int topf)
{
    id[u]=++cnt;
	top[u]=topf;
	rk[cnt]=u;
	
	if(!son[u]) return ;
	dfs2(son[u],topf);
	for(int i=head[u];i;i=a[i].next)
	{
		int v=a[i].v;
		if(!id[v]) dfs2(v,v);
	}
}
void update(int p)
{
	t[p].pre=t[ls].pre+t[rs].pre;
	t[p].minn=min(t[ls].minn,t[rs].minn);
}
void build(int p,int l,int r)
{
	t[p].l=l,t[p].r=r;
	if(l==r)
	{
	    t[p].minn=t[p].pre=b[t[p].l];
	    return ;
	}
	int mid=l+r>>1;
	build(ls,l,mid);build(rs,mid+1,r);
	update(p);
}
int ask1(int p,int x,int y)
{
	if(x<=t[p].l&&y>=t[p].r) return t[p].minn;
	int ans=N;
	int mid=t[p].l+t[p].r>>1;
	if(x<=mid) ans=min(ans,ask1(ls,x,y));
	if(y>mid) ans=min(ans,ask1(rs,x,y));
	return ans;
}
int ask2(int x,int y)
{
	int ans=N;
	if(find(x)!=find(y)) return -1;
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		ans=min(ans,ask1(1,id[top[x]],id[x]));
		x=f[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	ans=min(ans,ask1(1,id[x]+1,id[y]));
	return ans;
}
int main()
{
	n=read();m=read();
	for(int i=1 ;i<=m ;i++)
	tree[i].x=read(),tree[i].y=read(),tree[i].z=read();
	sort(tree+1,tree+1+m,cmp);
	kruskal();
	
	dfs1(1,0,1);
	dfs2(1,1);
	build(1,1,n);
	
	q=read();
	for(int i=1;i<=q;i++)
	{
		int u,v;
		u=read();v=read();
	    cout<<ask2(u,v)<<endl;
	} 
}
2020/9/29 21:03
加载中...