zoukankan      html  css  js  c++  java
  • AcWing397 逃不掉的路(边双)

    无向图缩点的low值定义是经过一条B边能够到的点的dfn的最小值

    如果low[v]>=low[u],说明有割点,但是要特判树边,如果low[v]>low[u],说明是有割边,但是要特判重边,本题很显然边双里的点都是不必要的

    只有桥是必要的,先缩点之后跑一下lca

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5e5+10;
    int h[N],ne[N],idx,e[N],cnt;
    int dfn[N],low[N],isce[N];
    int f[N][21];
    int ecc[N];
    int depth[N];
    int fa[N];
    vector<int> g[N];
    void add(int a,int b){
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    int n,m,times,ans;
    void tarjan(int u){
        dfn[u]=low[u]=++times;
        int i;
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(!dfn[j]){
                fa[j]=u;
                tarjan(j);
                low[u]=min(low[u],low[j]);
                if(dfn[u]<low[j]) isce[j]=1;
            }
            else if(j!=fa[u]) low[u]=min(low[u],dfn[j]);
        }
    }
    void dfs(int u,int x){
        ecc[u]=x;
        for(int i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(ecc[j]||fa[j]==u&&isce[j]||fa[u]==j&&isce[u])
            continue;
            dfs(j,x);
        }
    }
    void bfs(){
        queue<int> q;
        q.push(1);
        memset(depth,0x3f,sizeof depth);
        depth[0]=0,depth[1]=1;
        while(q.size()){
            int t=q.front();
            q.pop();
            int i;
            for(i=0;i<(int)g[t].size();i++){
                int j=g[t][i];
                if(depth[j]>depth[t]+1){
                    depth[j]=depth[t]+1;
                    q.push(j);
                    f[j][0]=t;
                    for(int k=1;k<=20;k++){
                        f[j][k]=f[f[j][k-1]][k-1];
                    }
                }
            }
        }
    }
    int lca(int a,int b){
        if(depth[a]<depth[b])
            swap(a,b);
        int i;
        for(i=20;i>=0;i--){
            if(depth[f[a][i]]>=depth[b]){
                a=f[a][i];
            }
        }
        if(a==b)
            return a;
        for(i=20;i>=0;i--){
            if(f[a][i]!=f[b][i]){
                a=f[a][i];
                b=f[b][i];
            }
        }
        
        return f[a][0];
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>m;
        int i;
        memset(h,-1,sizeof h);
        for(i=1;i<=m;i++){
            int a,b;
            cin>>a>>b;
            add(a,b);
            add(b,a);
        }
        tarjan(1);
        for(i=1;i<=n;i++){
            if(!ecc[i]){
                dfs(i,++cnt);
            }
        }
        for(i=1;i<=n;i++){
            int j;
            for(j=h[i];j!=-1;j=ne[j]){
                int k=e[j];
                if(ecc[i]==ecc[k])
                    continue;
                g[ecc[i]].push_back(ecc[k]);
            }
        }
        bfs();
        int qi;
        cin>>qi;
        while(qi--){
            int x,y;
            cin>>x>>y;
            x=ecc[x],y=ecc[y];
            int p=lca(x,y);
            cout<<depth[x]+depth[y]-2*depth[p]<<endl;
        }
    }
    View Code
  • 相关阅读:
    Large repunit factors (Project Euler 132)
    有向图 加最少的边 成为强连通分量的证明 poj 1236 hdu 2767
    ZJU 17th 校赛
    2015-2016ACM-ICPC NEER northern-subregional-contest C Concatenation
    BestCoder Round #93 ABC
    Codeforces Round #404 (Div. 2) DE
    Fibonacci数列的幂和 zoj 3774
    bitset在acm中的应用
    Codeforces Round #398 (Div. 2) BCD
    Hook length formula 学习笔记 UVALive 6625
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12963349.html
Copyright © 2011-2022 走看看