菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
14
0

tarjan

原创
05/13 14:22
阅读数 81422

tarjan 模板

int low[N],dfn[N],Stack[N],belong[N]; //最小下表,时间戳,一个用数组模拟的栈
//belong[x]表示x所属的强连通分量的编号
int idx,top;//,动态时间戳,栈顶
int scc;  //scc表示强连通分量的个数
bool instack[N];//是否在栈里面
int num[N];  //num[x]表示第x个强连通分量内所包含的点的个数
//前向星
void addedge(int u,int v){
    edge[tot].v = v;
    edge[tot].nxt = head[u];
    head[u] = tot++;
}
//模板
void tarjan(int u) {
    int v;
    low[u] = dfn[u] = ++idx;//记录时间戳
    Stack[top++] = u;//入栈
    instack[u] = 1;//标记u已经在栈中
    for(int i = head[u]; i != -1; i = edge[i].nxt) {//遍历边
        int v = edge[i].v;//v
        if(!dfn[v]) {//第一次访问
            tarjan(v);//dfs
            if(low[u]>low[v]) low[u] = low[v];//记录low
        }
        else if(instack[v]&&low[u]>dfn[v]) low[u] = dfn[v];//已经在栈中的点,可以用来更新low标记
    }
    if(low[u]==dfn[u]) {//弹栈
        scc++;//强连通个数加一
        do {
            v = Stack[--top];//弹栈
            instack[v] = 0;//标记不在栈中
            belong[v] = scc;//记录
            num[scc]++;//点集大小加一
        }
        while(v!=u);//跑路
    }

发表评论

0/200
14 点赞
0 评论
收藏