社区讨论

TLE95pts卡不过,玄关求条

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

讨论操作

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

当前回复
5 条
当前快照
1 份
快照标识符
@mjs3ucgu
此快照首次捕获于
2025/12/30 12:46
2 个月前
此快照最后确认于
2026/01/02 10:55
2 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 300005
#define LOG 20
int n,m,f[N],dep[N],s[N];
int fa[N][LOG];
int x[N],y[N],z[N];
vector<pair<int,int>> e[N];
//
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
template <typename T>
inline void read(T& r) {
	r=0;bool w=0; char ch=getchar();
	while(ch<'0'||ch>'9') w=ch=='-'?1:0,ch=getchar();
	while(ch>='0'&&ch<='9') r=r*10+(ch^48), ch=getchar();
	r=w?-r:r;
}
//
inline void dfs(int u,int faa){
	dep[u]=dep[faa]+1;
	fa[u][0]=faa;
	for(int i=1;i<LOG;i++)
		fa[u][i]=fa[fa[u][i-1]][i-1];
	for(pair<int,int> v:e[u])if(v.first!=faa){
		s[v.first]=s[u]+v.second;
		dfs(v.first,u);
	}
}
inline int lca(int u,int v){
	if(dep[u]<dep[v])swap(u,v);
	for(int i=LOG-1;i>=0;i--)
		if(dep[u]-(1LL<<i)>=dep[v])u=fa[u][i];
	if(u==v)return u;
	for(int i=LOG-1;i>=0;i--)
		if(fa[u][i]!=fa[v][i]){
			u=fa[u][i];
			v=fa[v][i];
		}
	return fa[u][0];
}
//
inline int gtdfs(int u,int faa,int cnt,int wei){
	int ans=0;
	for(pair<int,int> v:e[u])if(v.first!=faa){
		ans=max(ans,gtdfs(v.first,u,cnt,v.second));
		f[u]+=f[v.first];
	}
	if(f[u]==cnt)return max(ans,wei);
	else return ans;
}
// inline bool check(int k){
// 	for(int i=0;i<=n;i++)f[i]=0;
// 	int cnt=0,maxi=0;
// 	for(int i=1;i<=m;i++){
// 		maxi=max(maxi,z[i]);
// 		if(z[i]>k){
// 			f[x[i]]++;f[y[i]]++;
// 			f[lca(x[i],y[i])]-=2;
// 			cnt++;
// 		}
// 	}
// 	if(maxi-gtdfs(1,0,cnt,0)<=k)return 1;
// 	return 0;
// }
//
signed main()
{
	read(n);read(m);
	for(int i=1,u,v,w;i<n;i++){
		read(u);read(v);read(w);
		e[u].push_back({v,w});
		e[v].push_back({u,w});
	}
	dfs(1,0);
	int maxi=0;
	for(int i=1;i<=m;i++){
		read(x[i]);read(y[i]);
		z[i]=s[x[i]]+s[y[i]]-2*s[lca(x[i],y[i])];
		maxi=max(maxi,z[i]);
	}
	int l=0,r=INT_MAX,ans=r;
	while(l<=r){
		int k=l+r>>1;
		for(int i=0;i<=n;i++)f[i]=0;
		int cnt=0;
		for(int i=1;i<=m;i++){
			if(z[i]>k){
				f[x[i]]++;f[y[i]]++;
				f[lca(x[i],y[i])]-=2;
				cnt++;
			}
		}
		if(maxi-gtdfs(1,0,cnt,0)<=k){
			r=k-1;
			ans=min(ans,k);
		}
		else l=k+1;
	}
	cout<<ans;
	return 0;	
}

回复

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

正在加载回复...