Tarjan求图的连通性总结

有向图的Tarjan&缩点
void tarjan(int x){ //Tarjan 
        int y = 0;  
        dfn[x]=low[x]=++dindex;  
        instack[x]=true;  
        stap[++stop]=x;  
        for (int i=0; i<e[x].size(); i++) {  
            y=e[x][i];  
            if (!dfn[y]) {  
                tarjan(y);  
                if (low[y]<low[x]) {  
                    low[x]=low[y];  
                }  
            }  
            else if (instack[y]&&dfn[y]<low[x]){  
                low[x]=dfn[y];  
            }  
        }  
        if (dfn[x]==low[x]) {  
            cnt++;  
            while (y!=x) {  
                y=stap[stop--];  
                instack[y]=false;  
                belong[y]=cnt;  
            }  
        }  
    }  


for (int i=1; i<=n; i++) {  //求强连通分量
            if (!dfn[i]) {  
                tarjan(i);  
            }  
        }  



for (int i=1; i<=n; i++) {  
                int size=e[i].size();  
                for (int j=0; j<size; j++) {  
                    if (belong[i]!=belong[e[i][j]]) {  
                        outdeg[belong[i]]++;  
                        indeg[belong[e[i][j]]]++;  
                    }  
                }  
            }  
            int sumout=0,sumin=0;  
            for (int i=1; i<=cnt; i++) {  
                if (outdeg[i]==0) {  
                    sumout++;  
                }  
                if (indeg[i]==0) {  
                    sumin++;  
                }  
            }  
无向图的Tarjan
void tarjan_addedge(int u,int father)//Tarjan求无向图的割边
{
    int i,v;
    low[u]=dfn[u]=index++;
    for(i=head[u];i!=-1;i=edge[i].next)
    {
        v=edge[i].to;
        if(v==father)continue;
        if(dfn[v]==-1)
        {
            tarjan(v,u);
            low[u]=low[u]>low[v]?low[v]:low[u];
            if(low[v]>dfn[u])//桥
            {
                bridge[cnt++]=i;
            }
        }
        else low[u]=low[u]>dfn[v]?dfn[v]:low[u];
    }
}

来自 <http://acm.hust.edu.cn/vjudge/contest/source/6487492> 

void Tarjan_Point(int x)//Tarjan求无向图的割点
{
    id++;
    low[x] = dfn[x] = id;
    vis[x] = 1;
    for(int i = head[x]; i!=-1; i=edge[i].next)
    {
        int y=edge[i].v;
        if(!vis[y])
        {
            Tarjan(y);
            low[x] = min(low[x],low[y]);
            if(low[y] >= dfn[x] && x != 1)
            {
                num1[x]++;
            }
            else if(x == 1)
                numson++;
        }
        else
            low[x] = min(low[x],dfn[y]);
    }
}

来自 <http://acm.hust.edu.cn/vjudge/contest/source/6501942> 

if (low[v] != low[i])//无向图判断是不是一个双连通分量
{
    cnt[low[i]] ++;
}
来自 <http://acm.hust.edu.cn/vjudge/contest/source/6491720> 
posted @ 2016-07-21 16:20  adfae  阅读(222)  评论(0编辑  收藏  举报