社区讨论
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 条回复,欢迎继续交流。
正在加载回复...