Codeforces Round #805 (Div. 3) G2

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;
    }
}
posted @ 2022-11-29 21:26  ycllz  阅读(18)  评论(0)    收藏  举报