有向图的连通性

 跑完后

c[x]表示x所在的强连通分量编号。

vector数组scc[i]记录了编号为i的强连通分量的所有节点。

共cnt个强连通分量

int dfn[maxn],low[maxn],sta[maxn],c[maxn],ins[maxn];
vector<int>scc[maxn];
int num,top,cnt;
void tarjan(int x)
{
    dfn[x]=low[x]=++num;
    sta[++top]=x,ins[x]=1;
    for(int i=head[x];i;i=nextt[i])
    {
        int y=ver[i];
        if(!dfn[y]){
            tarjan(y);
            low[x]=min(low[x],low[y]);
        }
        else if(ins[y]){
            low[x]=min(low[x],dfn[y]);
        }
        
    }
    if(dfn[x]==low[x]){
        cnt++;int y;
        do{
            y=sta[top--],ins[y]=0;
            c[y]=cnt,scc[cnt].push_back(y);
        }while(x!=y);
    }
}

 

//main
//freopen("input.txt", "r", stdin);
scanf("%d%d",&x,&y);
for(int i=1;i<=n;++i){
    int x,y;
    scanf("%d%d",&x,&y);
    add(x,y);
}

for(int i =1 ;i <=n ;++i){
    if(!dfn[i]) tarjan(i);
}    

scanf("%d",&n);
for(int i = 1;i <= n; ++i){
    int y ;
    while(scanf("%d",&y)){
        if(y == 0) break;
        add(i,y);
    }
}

//缩点
for(int x = 1;x <= n;++x){
    for(int i = head[x];i ;i = nextt[i]){
        int y = ver[i];
        if(c[x] == c[y]) continue;
        add_c(c[x],c[y]);
    }
}

 

posted @ 2020-08-23 11:02  阿斯水生产线  阅读(190)  评论(0)    收藏  举报