• Evanyou Blog 彩带


      题目传送门

      啦啦啦,发个文纪念一下第一道在洛谷上A的黑题,一次性就过真是无比舒服~(虽然某些大佬说这题有点水……)题目其实思路不难,Tarjan缩点+LCA,不过因为是无向边,所以在Tarjan的时候做点标记就行了,不过第四个点会被卡,用vector存边就可以A掉了。另外输出用二进制这个应该没什么好说的。

      下面放代码:

      

    #include<cmath>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=10001;
    const int M=50001;
    int n,m,T,indexx,id,dep[N];
    int low[N],dfn[N],size[N];
    int f[N][21],belong[N];
    bool vis[N];
    vector<int>edge[M<<1];
    vector<int>node[M<<1];
    stack<int>team;
    inline int read()
    {
      char ch=getchar();int num=0;bool flag=false;
      while(ch<'0'||ch>'9'){if(ch=='-')flag=true;ch=getchar();}
      while(ch>='0'&&ch<='9'){num=num*10+ch-'0';ch=getchar();}
      return flag?-num:num;
    }
    inline int Min(int x,int y)
    {return x<y?x:y;}
    inline void tarjan(int u,int last)
    {
      dfn[u]=low[u]=++indexx;
      vis[u]=true;team.push(u);
      for(int i=0;i<node[u].size();i++){
        int v=node[u][i];
        if(v==last)continue;
        if(!dfn[v]){
          tarjan(v,u);
          low[u]=Min(low[u],low[v]);}
        else if(vis[v])
          low[u]=Min(low[u],dfn[v]);
      }
      if(dfn[u]==low[u]){
        int v;++id;
        do{
          v=team.top();team.pop();
          vis[v]=false;
          belong[v]=id;size[id]++;
        }while(v!=u);
      }
    }
    void build()
    {
      for(int i=1;i<=n;i++)
        for(int j=0;j<node[i].size();j++){
          int v=node[i][j];
          if(belong[i]!=belong[v])
        edge[belong[i]].push_back(belong[v]);
        }
    }
    inline void dfs(int u,int fa,int depth)
    {
      dep[u]=depth;f[u][0]=fa;
      for(int i=0;i<edge[u].size();i++)
        if(edge[u][i]!=fa)
          dfs(edge[u][i],u,depth+1);
    }
    void init()
    {
      for(int j=1;j<=20;j++)
        for(int i=1;i<=id;i++)
          f[i][j]=f[f[i][j-1]][j-1];
    }
    inline int LCA(int a,int b)
    {
      if(dep[a]<dep[b])swap(a,b);
      for(int i=20;i>=0;i--)
        if(dep[f[a][i]]>=dep[b])
          a=f[a][i];
      if(a==b)return a;
      for(int i=20;i>=0;i--)
        if(f[a][i]!=f[b][i])
          a=f[a][i],b=f[b][i];
      return f[a][0];
    }
    inline void print(int x)
    {
      if(x==0)return;
      print(x>>1);
      putchar(x%2+'0');
    }
    int main()
    {
      n=read();m=read();
      for(int i=1;i<=m;i++){
        int x=read();int y=read();
        node[x].push_back(y);
        node[y].push_back(x);}
      for(int i=1;i<=n;i++)
        if(!dfn[i])tarjan(i,0);
      build();dfs(1,0,0);init();
      T=read();
      for(int i=1;i<=T;i++){
        int x=read();int y=read();
        x=belong[x],y=belong[y];
        int lca=LCA(x,y);
        print((dep[x]+dep[y])-(dep[lca]<<1)+1);
        printf("
    ");
      }
      return 0;
    }
  • 相关阅读:
    C++雾中风景1:友元类与面向对象
    NFS服务器的安装与配置
    未来工作相关
    python 函数
    pycharm、sublime个性化设置
    hadoop中HDFS的NameNode原理
    Cat搭建遇坑记
    美团点评CAT监控平台研究
    阿里sentinel源码研究深入
    阿里熔断限流Sentinel研究
  • 原文地址:https://www.cnblogs.com/cytus/p/8469961.html
Copyright © 2020-2023  润新知