[gotoac]强连通+缩点

struct Node{
    int v,next;
}edge[M<<1];//原图的边
int now[M],init[M];//新图的邻接表表头,原图的邻接表表头
int pre[M],Index;//访问顺序
int low[M],idx[M],hash[M];//追溯的最早次序,点在新图的id,哈希新图的边
int ss[M],top;//放节点的栈
int n , nn , len;//原图大小,新图大小,边数(旧+新)
int m,_in[M],_out[M];//旧边数,新图入度,新图出度
 
void dfs(int u) {
    pre[u] = low[u] = Index ++;
    ss[++top] = u;
    for(int i = init[u] ; i != -1 ; i = edge[i].next) {
        int v = edge[i].v;
        if(pre[v] == -1) {
            dfs(v);
            low[u] = min(low[u] , low[v]);
        } else if(idx[v] == -1) {
            low[u] = min(low[u] , pre[v]);
        }
    }
    if(pre[u] == low[u]) {
        int v = -1;
        nn++;
        while(u != v) {
            v = ss[top--];
            idx[v] = nn;
        }
        now[nn] = -1;
    }
}
 
void Trajan() {
    memset(pre,-1,sizeof(int)*(n+1));
    memset(idx,-1,sizeof(int)*(n+1));
    Index = top = nn = 0;
    ss[0] = -1;
    for(int i=1;i<=n;i++) if(pre[i] == -1) dfs(i);
}
 
void shrink(){//缩点+求出缩点之后的入度出度
    memset(_in,0,sizeof(int)*(nn+1));
    memset(_out,0,sizeof(int)*(nn+1));
    memset(hash,-1,sizeof(int)*(nn+1));
    for(int u=1;u<=n;u++) {
        for(int i = init[u] ; i != -1 ; i = edge[i].next) {
            int v = edge[i].v;
            if(idx[u] != idx[v] && hash[idx[u]] != idx[v]) {
                hash[idx[u]] = idx[v];
                edge[len].next = now[ idx[u] ];
                edge[len].v = idx[v];
                now[ idx[u] ] = len++;
 
                _in[idx[v]]++,_out[idx[u]]++;
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值