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;
} 

 

posted @ 2019-11-08 15:06  水题收割者  阅读(158)  评论(0编辑  收藏  举报