G2. Passable Paths (hard version)
题链
我们思考一条链的特性
发现只要“确定”两端之后 就可以用LCA一遍判断是否是一条链的
我们如何确定两端 首先深度最深的一定是一端p1
另一端p2也可以用LCA判断 我们p2一定是与lca(p1,p2)!=p1,p2
让后我们也要最深的一个点
然后我们就O(nlog)判断即可
一般来说都是挂在一个点上的一条链 这个我们就枚举每一个p 他要吗在p1这边=>lca(p1,p)=p&&lca(p2,p)=lca(p1,p2)
在p2一边同理
还有一种特殊情况就是不是挂着 就是一条链 这样我们显然连p2都选不出来
void solve(){
cin>>n;
memset(h,-1,sizeof h);
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
add(u,v),add(v,u);
}
dfs(1);
int q;cin>>q;
while(q--){
int m;cin>>m;
int mx=-INF,p1,p2;
for(int i=0;i<m;i++){
cin>>a[i];
if(d[a[i]]>mx){
mx=d[a[i]];
p1=a[i];
}
}
mx=-INF;
int flag=0;
for(int i=0;i<m;i++){
if(lca(p1,a[i])!=a[i]&&d[a[i]]>mx){
mx=d[a[i]];
p2=a[i];
flag=1;
}
}
if(!flag){YES continue;}
int rt=lca(p1,p2);
for(int i=0;i<m;i++){
if((lca(a[i],p1)==a[i]&&lca(a[i],p2)==rt)||
(lca(a[i],p2)==a[i])&&lca(a[i],p1)==rt)continue;
else {NO goto out;}
}
YES
out:1;
}
}
标签:p2,p1,G2,int,Codeforces,lca,Div,mx
From: https://www.cnblogs.com/ycllz/p/16936775.html