• CF97E Leaders


    Link
    先搞一个生成树,那么两个点之间存在奇数长度的路径等价于两点之间树上距离为奇数或者两点之间路径上存在一个奇环。
    对于一个v-dcc,如果该v-dcc中存在一个奇环,那么该v-dcc内所有边都在至少一个奇环上。
    那么我们缩点然后差分维护即可。

    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<algorithm>
    namespace IO
    {
        char ibuf[(1<<21)+1],*iS,*iT;
        char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
        int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
    }
    using IO::read;
    const int N=100007;
    std::vector<int>e[N];
    int t,cnt,top,dep[N],fa[N][17],root[N],sum[N],dfn[N],low[N],stk[N],ins[N],bel[N],is[N];
    void dfs(int u)
    {
        for(int i=1;i<=16;++i) fa[u][i]=fa[fa[u][i-1]][i-1];
        for(int v:e[u])if(!dep[v])fa[v][0]=u,dep[v]=dep[u]+1,root[v]=root[u],dfs(v);
    }
    int lca(int u,int v)
    {
        if(dep[u]<dep[v]) std::swap(u,v);
        for(int i=16;~i;--i) if(dep[fa[u][i]]>=dep[v]) u=fa[u][i];
        for(int i=16;~i;--i) if(fa[u][i]^fa[v][i]) u=fa[u][i],v=fa[v][i];
        return u^v? fa[u][0]:u;
    }
    void dfs2(int u){for(int v:e[u])if(fa[v][0]==u)sum[v]+=sum[u],dfs2(v);}
    void tarjan(int u,int fa)
    {
        dfn[u]=low[u]=++t,stk[++top]=u,ins[u]=1;
        for(int v:e[u]) if(v^fa) !dfn[v]? (tarjan(v,u),low[u]=std::min(low[u],low[v])):low[u]=std::min(low[u],dfn[v]);
        if(dfn[u]==low[u]) for(++cnt;stk[top+1]^u;) ins[stk[top]]=0,bel[stk[top--]]=cnt;
    }
    int main()
    {
        int n=read(),m=read();
        for(int i=1,u,v;i<=m;++i) u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
        for(int u=1;u<=n;++u) if(!dep[u]) dep[u]=1,dfs(root[u]=u);
        for(int u=1;u<=n;++u) if(dep[u]==1) tarjan(u,0);
        for(int u=1;u<=n;++u) if(!is[bel[u]]) for(int v:e[u]) if(!((dep[u]+dep[v])&1)&&bel[u]==bel[v]) {is[bel[u]]=1;break;}
        for(int u=1;u<=n;++u) if(fa[u][0]&&bel[u]==bel[fa[u][0]]&&is[bel[u]]) ++sum[u];
        for(int u=1;u<=n;++u) if(dep[u]==1) dfs2(u);
        for(int q=read(),u,v;q;--q) u=read(),v=read(),puts(root[u]^root[v]||u==v||(!((dep[u]+dep[v])&1)&&sum[u]+sum[v]==2*sum[lca(u,v)])? "No":"Yes");
    }
    
  • 相关阅读:
    python基础篇 08 文件操作
    python基础篇 07set集合 深浅拷贝
    python 基础篇 06 编码 以及小知识点补充
    python基础篇 05字典
    钉钉中设置代码提交提醒--Github机器人(转)
    Spring Boot 之FilterRegistrationBean --支持web Filter 排序的使用(转)
    Spring Aop实例@Aspect、@Before、@AfterReturning@Around 注解方式配置(转)
    为什么添加了@Aspect 还要加@Component(转)
    Servlet 服务器 HTTP 响应
    Servlet 客户端 HTTP 请求
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12287478.html
Copyright © 2020-2023  润新知