标签:题目 amp sizeof oid space swa solution eof ons
题目链接:Click here
我们要使最大值最小,显然二分
二分一个最大值,小于等于最大值的路径就不用管了,看大于最大值的路径
记录要使剩下的路径的最大值小于等于当前二分的值,要减去的最小边长maxd
然后我们就是要查找是否有一条被剩下的所有路径都经过的,长度大于等于maxd边
我们可以用树上差分来记录一条边被多少条路径经过
对于一条路径,我们使\(d[u]++\),\(d[v]++\),\(d[lca(u,v)]-2\),\(f[x]\)代表以\(x\)为根的子树\(d\)值之和
对于任意\(f[x]=tot\),则说明\(x\)连向\(fa[x]\)的这条边被所有路径都经过了
用倍增求lca会T,所以我们用树剖来求lca(关于倍增,它死了>)
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+1;
int n,m,cnt,head[N],dis[N],fdis[N];
int maxn,f[N][32],dif[N],dep[N];
int son[N],sz[N],fa[N],top[N];
struct Edge{int nxt,to,val;}edge[N<<1];
struct Road{int ds,u,v,lca;}p[N];
void ins(int x,int y,int z){
edge[++cnt].nxt=head[x];
edge[cnt].to=y;head[x]=cnt;
edge[cnt].val=z;
}
void dfs1(int x,int fat){
for(int i=head[x];i;i=edge[i].nxt){
int y=edge[i].to;
if(y==fat) continue;
fa[y]=x;dep[y]=dep[x]+1;
dis[y]=dis[x]+edge[i].val;
fdis[y]=edge[i].val;
dfs1(y,x);sz[x]+=sz[y];
if(sz[y]>sz[son[x]]) son[x]=y;
}sz[x]++;
}
void dfs2(int x,int topx){
top[x]=topx;
if(!son[x]) return ;
dfs2(son[x],topx);
for(int i=head[x];i;i=edge[i].nxt){
int y=edge[i].to;
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
int Lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
return x;
}
int dist(int x,int y){
return dis[x]+dis[y]-(dis[Lca(x,y)]<<1);
}
void getdif(int x){
for(int i=head[x];i;i=edge[i].nxt){
int y=edge[i].to;
if(y==fa[x]) continue;
getdif(y);dif[x]+=dif[y];
}
}
int check(int mid){
int tot=0,maxd=0;
memset(dif,0,sizeof(dif));
for(int i=1;i<=m;i++){
if(p[i].ds<=mid) continue;
dif[p[i].u]++,dif[p[i].v]++;
dif[p[i].lca]-=2;++tot;
maxd=max(maxd,p[i].ds-mid);
}getdif(1);
for(int i=2;i<=n;i++)
if(maxd<=fdis[i]&&dif[i]>=tot) return 1;
return 0;
}
int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
signed main(){
n=read(),m=read();
for(int i=1;i<n;i++){
int x=read(),y=read(),z=read();
ins(x,y,z),ins(y,x,z);
}dfs1(1,0);dfs2(1,1);
for(int i=1;i<=m;i++){
int x=read(),y=read();
p[i].u=x,p[i].v=y;
p[i].lca=Lca(x,y);
p[i].ds=dist(x,y);
maxn=max(maxn,p[i].ds);
}
int l=0,r=maxn,re=-1;
while(l<=r){
int mid=l+r>>1;
if(check(mid)) re=mid,r=mid-1;
else l=mid+1;
}printf("%d\n",re);
return 0;
}
标签:题目 amp sizeof oid space swa solution eof ons
原文地址:https://www.cnblogs.com/NLDQY/p/11518644.html