社区讨论

95分,求调

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

讨论操作

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

当前回复
7 条
当前快照
1 份
快照标识符
@mhj44kaq
此快照首次捕获于
2025/11/03 20:24
4 个月前
此快照最后确认于
2025/11/03 20:24
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
struct node
{
	long long to,w,nxt;
} e[3000005];
struct lm
{
	long long u,v;
} a[3000005];
long long hd[3000005],idx=1,l,r,dis[3000005],DIS[3000005],LCA[3000005],lg[3000005],n,m,max1,max2,cnt,d[3000005],dep[3000005],f[3000005][20];
void add(long long u,long long v,long long w)
{
	 e[++idx].nxt=hd[u];
	 hd[u]=idx;
	 e[idx].to=v;
	 e[idx].w=w;
}
void dfs(long long x,long long lst,long long sum){
	 dep[x]=dep[lst]+1;
	 dis[x]=sum;
	 f[x][0]=lst;
	 for(long long i=1;i<=lg[dep[x]];i++)
	 {
		 long long z=f[x][i - 1]; 
		 f[x][i]=f[z][i - 1];
	 }
	 for(long long i=hd[x];i;i=e[i].nxt)
	 {
		 long long id=e[i].to,w=e[i].w;
		 if(id==lst) continue;
		 dfs(id,x,sum+w);
	 } 
}
void dfs2(long long x,long long lst,long long sum)
{
	 for(long long i=hd[x];i;i=e[i].nxt)
	 {
		 long long id=e[i].to,w=e[i].w;
		 if(id==lst) continue;
		 dfs2(id,x,w);
		 d[x]+=d[id];
	 }
	 if(d[x]==cnt) max2=max(max2,sum);
}
long long lca(long long x,long long y)
{
    if(dep[x]<dep[y]) swap(x,y);
    for(long long i=19;i>=0;i--) if(dep[f[x][i]]>=dep[y])x=f[x][i];
    if(x==y) return x;
    for(long long i=19;i>=0;i--) if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
    return f[x][0];
}
bool check(long long mid)
{
	 memset(d, 0, sizeof(d)); 
	 cnt = max1 = max2 = 0;
	 for(long long i = 1; i <= m; i++)
	 {
		 if(DIS[i] <= mid) continue;
		 max1=max(max1, DIS[i]);
		 cnt++;
		 d[a[i].u]++,d[a[i].v]++;
		 d[LCA[i]]-=2;
	 }
	 if(cnt == 0) return 1;
	 dfs2(1,0,0);
	 return max1-max2<=mid;
}
int main()
{
    ios::sync_with_stdio(0); 
    cin.tie(0);
    cin >> n >> m;
	for(long long i=2;i<=n;i++) lg[i]=lg[i/2]+1;
	for(long long i=1;i<n;i++)
	{
		long long x,y,z;
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	dfs(1,0,0);
	for(long long i=1;i<=m;i++)
	{
		long long u,v;
		cin>>u>>v;
		a[i]={u,v};
		LCA[i]=lca(u,v);
		DIS[i]=dis[u]+dis[v]-2*dis[LCA[i]];
		r=max(r,DIS[i]);
	}
	while(l<r)
	{
		long long mid=l+r>>1;
		if(check(mid)) r=mid;
		else l=mid+1;
	}
	cout << l;
    return 0;
}

回复

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

正在加载回复...