95分 WA on #13 求助
查看原帖
95分 WA on #13 求助
364159
PhosEe楼主2023/1/13 21:40
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
#define in read()
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=(x<<1)+(x<<3)+c-'0';
		c=getchar();
	}
	return x*f;
}
struct edge{
	int u,v,w,nxt;
}e[maxn<<1];
int cnt=0,h[maxn];
void add(int u,int v,int w){
	e[++cnt]=(edge){u,v,w,h[u]};
	h[u]=cnt;
}
int n,m,u,v,t,l,r,maxlen,tim,st[maxn],val[maxn],dfn[maxn],fa[maxn],dep[maxn],dis[maxn];
void dfs(int x,int father,int d){
	dfn[++tim]=x;
	st[x]=tim;
	fa[x]=father;
	dep[x]=d;
	for(int i=h[x];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==father) continue;
		dis[v]=dis[x]+e[i].w;
		val[v]=e[i].w;
		dfs(v,x,d+1);
		dfn[++tim]=x;
	}
}
int f[maxn<<1][24];
int mmin(int a,int b){
	return dep[a]<dep[b]?a:b;
}
void STinit(int len){
	for(int i=1;i<=len;i++) f[i][0]=dfn[i];
	for(int j=1;(1<<j)<=len;j++){
		for(int i=1;i+(1<<j-1)<len;i++){
			f[i][j]=mmin(f[i][j-1],f[i+(1<<j-1)][j-1]);
		}
	}
}
int lca(int x,int y){
	x=st[x];y=st[y];
	if(x>y) swap(x,y);
	int k=0;
	while((1<<k+1)<=(y-x+1)) k++;
	return mmin(f[x][k],f[y-(1<<k)+1][k]);
}
struct roads{
	int u,v,Lca,dis;
}rr[maxn];
int s[maxn];
void dfs2(int x,int fa){
	for(int i=h[x];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fa) continue;
		dfs2(v,x);
		s[x]+=s[v];
	}
}
bool check(int mid){
	int	res=0;
	memset(s,0,sizeof(s));
	for(int i=1;i<=m;i++){
		if(rr[i].dis>mid){
			res++;
			s[rr[i].u]++;
			s[rr[i].v]++;
			s[rr[i].Lca]-=2;
		}
	}
	if(res==0) return true;
	dfs2(1,0);
	int maxn=0;
	for(int i=1;i<=n;i++){
		if(s[i]==res) maxn=maxn>val[i]?maxn:val[i]; 
	}
	return maxlen-maxn<=mid;
}
int main(){
	n=in;m=in;
	for(int i=1;i<n;i++){
		u=in;v=in;t=in;
		add(u,v,t);
		add(v,u,t);
	}
	dfs(1,0,1);
	STinit(tim);
	for(int i=1;i<=m;i++){
		rr[i].u=in;rr[i].v=in;
		rr[i].Lca=lca(rr[i].u,rr[i].v);
		rr[i].dis=dis[rr[i].u]+dis[rr[i].v]-2*dis[rr[i].Lca];
		r=r>rr[i].dis?r:rr[i].dis;
	}
	maxlen=r;int ans=0;
	while(l<=r){
		int mid=l+r>>1;
		if(check(mid)){
			ans=mid;
			r=mid-1;
		}else l=mid+1;
	}
	printf("%d\n",ans);
	return 0;
}
2023/1/13 21:40
加载中...