【CF555E】Case of Computer Network

题面

https://www.luogu.org/problem/CF555E

题解

#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>

using namespace std;

struct stack{
  int a[200050],tail;
  bool b[200050];
  void clear() {memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); tail=0;}
  void push(int x) {++tail; a[tail]=x; b[x]=true;}
  int top() {return a[tail];}
  void pop() {b[a[tail]]=false; tail--;}
  bool isin(int x) {return b[x];}
} stk;

int n,m,q,dfn[200050],low[200050],cloct=0;
int bel[200050],cnt=0;
int s[200050],t[200050];
vector<int> to[200050],id[200050];
vector<int> about[200050];
int f[200050][25],d[200050];
int f1[200050],f2[200050];
bool ans;

void tarjan(int now,int faid){
  low[now]=dfn[now]=++cloct;
  stk.push(now);
  int i,l=to[now].size();
  for (i=0;i<l;i++) if (id[now][i]!=faid) {
      if (!dfn[to[now][i]]) {
        tarjan(to[now][i],id[now][i]);
        low[now]=min(low[now],low[to[now][i]]);
    }
    else {
      if (stk.isin(to[now][i])) {
          low[now]=min(low[now],dfn[to[now][i]]);
      }
    }
  }
  if (low[now]==dfn[now]) {
    int x;
    ++cnt;
    do {
      x=stk.top();
      bel[x]=cnt;
      stk.pop();
    } while (x!=now);
  }
}

void maketree(int now,int fa,int deep){
  int i,l=about[now].size();
  f[now][0]=fa;
  for (i=1;i<=19;i++) f[now][i]=f[f[now][i-1]][i-1];
  d[now]=deep;
  for (i=0;i<l;i++) if (about[now][i]!=fa) maketree(about[now][i],now,deep+1);
}

void work(int u,int v){
  f1[u]+=1; f1[v]-=1;
  f2[u]+=1; f2[v]+=1;
  if (d[u]<d[v]) swap(u,v);
  int i,lca;
  for (i=19;i>=0;i--) if (d[f[u][i]]>=d[v]) u=f[u][i];
  if (u==v) lca=u;
  else {
    for (i=19;i>=0;i--) if (f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
    lca=f[u][0];
  }
  f2[lca]-=2;
}

void treesum(int now,int fa) {
  int i,l=about[now].size();
  for (i=0;i<l;i++) if (about[now][i]!=fa) {
    treesum(about[now][i],now);
    f1[now]+=f1[about[now][i]];
    f2[now]+=f2[about[now][i]];
  }
  if (abs(f1[now])!=abs(f2[now])) ans=false;
}

int main(){
  int i,u,v,from,to0;
  scanf("%d %d %d",&n,&m,&q);
  for (i=1;i<=m;i++) {
      scanf("%d %d",&u,&v);
      s[i]=u; t[i]=v;
      to[u].push_back(v); id[u].push_back(i);
      to[v].push_back(u); id[v].push_back(i);
  }
  stk.clear();
  for (i=1;i<=n;i++) if (!dfn[i]) tarjan(i,-1);
  for (i=1;i<=m;i++) {
      if (bel[s[i]]!=bel[t[i]]) {
      about[bel[s[i]]].push_back(bel[t[i]]);
      about[bel[t[i]]].push_back(bel[s[i]]);
    }
  }
  for (i=1;i<=cnt;i++) if (!f[i][0]) maketree(i,i,1);
  ans=true;
  for (i=1;i<=q;i++) {
    scanf("%d %d",&from,&to0);
    //printf("%d %d\n",bel[from],bel[to0]);
    //printf("%d %d\n",f[bel[from]][19],f[bel[to0]][19]);
    if (f[bel[from]][19]!=f[bel[to0]][19]) {ans=false; continue;}
    if (bel[from]!=bel[to0]) work(bel[from],bel[to0]);
    //val[from]=1; val[to]=-1;
  }
  //for (i=1;i<=n;i++) cout<<bel[i]<<" ";
  treesum(1,-1);
  if (ans) puts("Yes"); else puts("No");
}

猜你喜欢

转载自www.cnblogs.com/shxnb666/p/11427337.html