55pts球调
查看原帖
55pts球调
1034667
Elysian_Realme楼主2024/5/2 19:27
// Problem: P2680 [NOIP2015 提高组] 运输计划
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2680
// Memory Limit: 292 MB
// Time Limit: 1000 ms
// 
// By:lmq
// AC Time:2024-04-18 20:32:55

#include <bits/stdc++.h>
using namespace std;
struct edge{
	int v,w;
};
struct flight{
	int u,v,l;
}a[300005];
int n,m;
int d[300005];
int ds[300005];
int f[300005][50];
int wt[300005][30];
vector<edge> g[300005];
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
void dfs_lca(int u,int fa){
	f[u][0]=fa,ds[u]=ds[fa]+1;
	for(int i=1;(1<<i)<=ds[u];i++)
		f[u][i]=f[f[u][i-1]][i-1],wt[u][i]=wt[u][i-1]+wt[f[u][i-1]][i-1];
	for(edge i:g[u]){
		if(i.v!=fa){
			wt[i.v][0]=i.w,dfs_lca(i.v,u);
		}
	}
}
void dfs_sum(int u,int fa){
	for(edge i:g[u])
		if(i.v!=fa)
			dfs_sum(i.v,u),d[u]+=d[i.v];
}
int lca(int tp,int x,int y){
	int res=0;
	if(ds[x]>ds[y])swap(x,y);
	while(ds[x]<ds[y]){
		res+=wt[y][__lg(ds[y]-ds[x])];
		y=f[y][__lg(ds[y]-ds[x])];
	}
	for(int i=__lg(ds[x]);i>=0;i--)
		if(f[x][i]!=f[y][i])
			res+=wt[x][i]+wt[y][i],x=f[x][i],y=f[y][i];
	if(tp==1)return res+wt[x][0]+wt[y][0];
	return f[x][0];
}
inline void add(int u,int v){
	int p=lca(2,u,v);
	d[u]++,d[v]++,d[p]-=2;
}
bool check(int k){
	int cnt=0,mx=0;
	memset(d,0,sizeof(d));
	for(int i=1;i<=m;i++)
		if(a[i].l>k)
			cnt++,mx=max(mx,a[i].l),add(a[i].u,a[i].v);
	if(cnt==0)return 1;
	dfs_sum(1,0);
	for(int i=1;i<=n;i++){
		if(d[i]==cnt&&mx-wt[i][0]<=k)
			return 1;
	}
	return 0;
}
signed main(){
	cin>>n>>m;
	int l=-1,r=0;
	for(int i=1;i<n;i++){
		int u,v,w;cin>>u>>v>>w;r+=w;
		g[u].push_back((edge){v,w});
		g[v].push_back((edge){u,w});
	}
	r++;
	dfs_lca(1,0);
	for(int i=1;i<=m;i++){
		a[i].u=read(),a[i].v=read();
		a[i].l=lca(1,a[i].u,a[i].v);
	}
	while(l+1!=r){
		int mid=(l+r)>>1;
		if(check(mid))
			r=mid;
		else l=mid;
	}
	cout<<r<<endl;
	return 0;
}
2024/5/2 19:27
加载中...