• 555E Case of Computer Network


    分析

    一个连通块内的肯定不影响

    于是我们先缩点

    之后对于每个路径

    向上向下分别开一个差分数组

    如果两个数组同时有值则不合法

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,q,bl[200100],s[200100],t[200100],dfn[200100],low[200100],is[200100];
    int cnt,tot,sum,head[200100],nxt[400100],to[400100],ano[400100];
    int d1[200100],d2[200100],dep[200100],pr[200100][23];
    int f[200100],vis[200100],vis2[200100];
    vector<int>v[200100];
    stack<int>a;
    inline int sf(int x){return f[x]==x?x:f[x]=sf(f[x]);}
    inline void add(int x,int y){
        nxt[++tot]=head[x],head[x]=tot,to[tot]=y,ano[tot]=tot+1;
        nxt[++tot]=head[y],head[y]=tot,to[tot]=x,ano[tot]=tot-1;
    }
    inline void tarjan(int x,int id){
        dfn[x]=low[x]=++cnt;
        a.push(x),is[x]=1;
        for(int i=head[x];i;i=nxt[i])
          if(i!=ano[id]){
            if(!dfn[to[i]]){
                tarjan(to[i],i);
                low[x]=min(low[x],low[to[i]]);
            }else if(is[to[i]]){
                low[x]=min(low[x],dfn[to[i]]);
            }
          }
        if(low[x]==dfn[x]){
          sum++;
          while(1){
              int u=a.top();
              a.pop(),is[u]=0;
              bl[u]=sum;
              if(u==x)break;
          }
        }
    }
    inline void dfs(int x,int fa){
        vis2[x]=1;
        pr[x][0]=fa;
        dep[x]=dep[fa]+1;
        for(int i=0;i<v[x].size();i++)
          if(v[x][i]!=fa)dfs(v[x][i],x);
    }
    inline int lca(int x,int y){
        if(dep[x]<dep[y])swap(x,y);
        int i,j,k,len=dep[x]-dep[y];
        for(i=0;i<=20;i++)
          if((1<<i)&len)x=pr[x][i];
        if(x==y)return x;
        for(i=20;i>=0;i--)
          if(pr[x][i]!=pr[y][i])
            x=pr[x][i],y=pr[y][i];
        return pr[x][0];
    }
    inline void dfs2(int x,int fa){
        vis[x]=1; 
        for(int i=0;i<v[x].size();i++)
          if(v[x][i]!=fa)dfs2(v[x][i],x),d1[x]+=d1[v[x][i]],d2[x]+=d2[v[x][i]];
        if(d1[x]>0&&d2[x]>0){
          puts("No");
          exit(0);
        }
    }
    int main(){
        int i,j,k;
        scanf("%d%d%d",&n,&m,&q);
        for(i=1;i<=m;i++){
          int x,y;
          scanf("%d%d",&x,&y);
          add(x,y);
          if(sf(x)!=sf(y))f[sf(x)]=sf(y);
        }
        for(i=1;i<=q;i++)scanf("%d%d",&s[i],&t[i]);
        for(i=1;i<=q;i++)if(sf(s[i])!=sf(t[i])){puts("No");return 0;}
        for(i=1;i<=n;i++)if(!dfn[i])tarjan(i,0);
        for(i=1;i<=n;i++)
          for(j=head[i];j;j=nxt[j])
            if(bl[i]!=bl[to[j]])v[bl[i]].push_back(bl[to[j]]);
        for(i=1;i<=sum;i++)if(!vis2[i])dfs(i,0);
        for(i=1;i<=20;i++)
          for(j=1;j<=sum;j++)
            pr[j][i]=pr[pr[j][i-1]][i-1];
        for(i=1;i<=q;i++){
          if(bl[s[i]]==bl[t[i]])continue;
          int x=bl[s[i]],y=bl[t[i]],z=lca(x,y);
          d1[x]++,d1[z]--;
          d2[y]++,d2[z]--;
        }
        for(i=1;i<=sum;i++)if(!vis[i])dfs2(i,0);
        puts("Yes");
        return 0;
    } 
  • 相关阅读:
    Poj3126
    Poj1426
    2806 红与黑
    3100 蜗牛
    1225 八数码难题
    2549 自然数和分解
    2547 东方辉针城
    2928 你缺什么
    1629 01迷宫
    1029 遍历问题
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/11820343.html
Copyright © 2020-2023  润新知