zoukankan      html  css  js  c++  java
  • 模板 两次dfs

    第一次dfs为后序遍历
    第二次dfs将所有边反向,从编号最大的顶点开始(也就是原图缩点后形成的DAG根节点所在的强连通分量),由于边反向后,不能由这个强连通分量访问到其他强连通分量的顶点,而强连通分量内部之间的顶点不受影响,所以每一次dfs所遍历到的所有顶点形成一个强连通分量
    通过这种算法得到的强连通分量的编号表示DAG上的一种拓扑序
    算法进行了两次dfs,时间复杂度(O(|V|+|E|))

    const int maxn=10010,maxm=50010;
    int n,m,head[maxn],nxt[maxm],to[maxm],cnt=1;
    int rhead[maxn],rnxt[maxm],rto[maxm];
    int book[maxn],comp[maxn];
    vector<int> vs;
    
    void dfs(int u){
        book[u]=1;
        for(int i=head[u];i;i=nxt[i]){
            int v=to[i];
            if(!book[v]) dfs(v);
        }  
        vs.push_back(u);
    }
    
    void rdfs(int u,int k){
        book[u]=1;
        comp[u]=k;
        for(int i=rhead[u];i;i=rnxt[i]){
            int v=rto[i];
            if(!book[v]) rdfs(v,k);
        }
    }
    
    int scc(){
        memset(book,0,sizeof(book));
        vs.clear();
        for(int i=0;i<n;i++){
            if(!book[i]) dfs(i);
        }
        memset(book,0,sizeof(book));
        int k=0;
        for(int i=vs.size()-1;i>=0;i--){
            if(!book[vs[i]]) rdfs(vs[i],k++);
        }
        return k;
    }
    
  • 相关阅读:
    级联操作
    深入解析http协议
    http状态码
    数据库在一对一、一对多、多对多怎么设计表关系
    [转载]C#深拷贝的方法
    TraceSource记录程序日志
    .NET 垃圾回收与内存泄漏
    DevExpress GridControl使用方法总结
    DevExpress使用技巧总结
    Oracle 错误代码小结
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13410545.html
Copyright © 2011-2022 走看看