社区讨论

95pts求卡常,悬关

P2680[NOIP 2015 提高组] 运输计划参与者 4已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mhjsf04i
此快照首次捕获于
2025/11/04 07:44
4 个月前
此快照最后确认于
2025/11/04 07:44
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
template<typename T>void read(T &x){
	x=0;char c=getchar();int f=1;
	for(;!isdigit(c);c=getchar())if(f=='-')f=-1;
	for(;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c^48);
	x*=f;
}
int n,m,tot,mx,maxlen;
struct tree{
	int v,w;
};
vector<tree>T[maxn];
struct edge{
	int u,v,x,len;
}a[maxn];
int dep[maxn],dis[maxn],fa[maxn][30],d[maxn],k[maxn];
inline void make_info(int u,int F){
	dep[u]=dep[F]+1;
	fa[u][0]=F;
	for(register int j=1;(1<<j)<=dep[u];++j) fa[u][j]=fa[fa[u][j-1]][j-1];
	for(auto e:T[u]){
		int v=e.v,w=e.w;
		if(v==F) continue;
		dis[v]=dis[u]+w;
		d[v]=w;
		make_info(v,u);
	}
}
inline int lca(int u,int v){
	if(dep[u]<dep[v]) swap(u,v);
	int k=log2(n);
	for(register int j=k;j>=0;--j){
		if(dep[fa[u][j]]>=dep[v]){
			u=fa[u][j];
		}
	}
	if(u==v) return u;
	for(register int j=k;j>=0;--j){
		if(fa[u][j]!=fa[v][j]){
			u=fa[u][j];
			v=fa[v][j];
		}
	}
	return fa[u][0];
}
inline bool cmp(edge p,edge q){
	return p.len>q.len;
}
inline void dfs(int u,int F){
	for(auto e:T[u]){
		int v=e.v,w=e.w;
		if(v==F) continue;
		dfs(v,u);
		k[u]+=k[v];
	}
	if(k[u]==tot) mx=max(mx,d[u]); 
}
inline bool check(int mid){
	for(register int i=1;i<=n;++i) k[i]=0;
	tot=0;
	for(register int i=1;i<=m;++i){
		if(a[i].len>mid){
			tot++;
			int u=a[i].u,v=a[i].v,x=a[i].x;
			k[u]++;k[v]++;k[x]-=2;
		}
	}
	mx=0;
	dfs(1,0);
	return maxlen-mx<=mid;
}
int main(){
	read(n);read(m);
	for(register int i=1;i<n;++i){
		int u,v,w;
		read(u);read(v);read(w);
		T[u].push_back((tree){v,w});
		T[v].push_back((tree){u,w});
	}
	make_info(1,0);
	for(register int i=1;i<=m;++i){
		int u,v;
		read(u);read(v);
		int x=lca(u,v);
		int L=dis[u]+dis[v]-2*dis[x];
		maxlen=max(maxlen,L);
		a[i]=(edge){u,v,x,L};
	}
//	sort(a+1,a+m+1,cmp);
	int l=0,r=maxlen,ans;
	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;
}

回复

4 条回复,欢迎继续交流。

正在加载回复...