• 【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
    ",bel[from],bel[to0]);
        //printf("%d %d
    ",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");
    }
  • 相关阅读:
    古典密码-移位密码|埃特巴什密码Atbash
    古典密码-凯撒密码Caeser
    古典密码-维吉尼亚密码Vigenere
    使用kubeadm搭建一个k8s集群
    用户态线程和内核态线程的区别
    模板合集
    NoteExpress 章节合并后如何更新参考文献列表?
    CSDN 博客园主题
    GShang的博客园2020年终总结
    【比赛记录】CodeChef January Challenge 2021
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11427337.html
Copyright © 2020-2023  润新知