zoukankan      html  css  js  c++  java
  • Tarjan算法总结

    边双联通分量

    inline void Tarjan(int x,int inedge)
    {
        dfn[x]=low[x]=++cnt;
        for(int i=Last[x];i;i=e[i].next)
        {
            int y=e[i].ver;
            if(!dfn[y])
            {
                Tarjan(y,i);
                low[x]=min(low[x],low[y]);
                if(low[y]>dfn[x])e[i].flag=e[i^1].flag=true;
            }
            else if(i!=(inedge^1))low[x]=min(low[x],dfn[y]);
        }
    }
    inline void dfs(int x)
    {
        con[x]=tot;
        for(int i=Last[x];i;i=e[i].next)
        {
            if(e[i].flag)continue;
            int y=e[i].ver;
            if(!con[y])dfs(y);
        }
    }
    inline void colored(void)
    {
        for(int i=1;i<=n;i++)
            if(!con[i])++tot,dfs(i);
    }
    

    点双连通分量

    inline void Tarjan(int x,int root)
    {
        dfn[x]=low[x]=++cnt;
        Stack.push(x);
        int flag=0;
        if(x==root&&!Last[x])
        {
            Stack.pop();T++;
            cut[x]=true;
            con[T].push_back(x);
            return;
        }
        for(int i=Last[x];i;i=e[i].next)
        {
            int y=e[i].ver;
            if(!dfn[y])
            {
                Tarjan(y,root);
                low[x]=min(low[x],low[y]);
                if(low[y]>=dfn[x])
                {
                    int top=0;T++;
                    while(top!=y)
                    {
                        top=Stack.top();
                        Stack.pop();
                        con[T].push_back(top);
                    }
                    con[T].push_back(x);
                    flag++;
                    if(x!=root||flag>1)cut[x]=true;
                }
            }
            else low[x]=min(low[x],dfn[y]);
        }
    }
    

    强连通分量

    void Tarjan(int x)
    {
    	dfn[x]=low[x]=++tim;
    	s[++top]=x;
    	for(int i=head[x];i;i=nxt[i]){
    		int y=ver[i];
    		if(!dfn[y]){
    			Tarjan(y);
    			low[x]=min(low[x],low[y]);
    		}
    		else if(!sccno[y]) low[x]=min(low[x],dfn[y]);
    	}
    	if(dfn[x]==low[x]){
    		cnt++;
    		while(1){
    			int y=s[top--];
    			sccno[y]=cnt;
    			num[cnt]++;
    			if(y==x) break;
    		}
    	}
    }
    
  • 相关阅读:
    策略模式
    模板方法模式

    kafka
    Linux下部署MongoDB
    Linux下安装ssdb
    ssdb常用知识点
    Eclipse 的 Java Web 项目环境搭建
    PLSQL连接Oracle
    redis书籍
  • 原文地址:https://www.cnblogs.com/LSlzf/p/13273150.html
Copyright © 2011-2022 走看看