Tarjan算法求有向图强连通分量并缩点

// Tarjan算法求有向图强连通分量并缩点
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int N = 100010, M = 1000010;
//
int ver[M], Next[M], head[N], dfn[N], low[N];
int stack[N], ins[N], c[N];

int vc[M], nc[M], hc[N], tc;
//强连通分量
vector<int> scc[N];

int n, m, tot, num, top, cnt;

void add(int x, int y) {
    ver[++tot] = y, Next[tot] = head[x], head[x] = tot;
}
//缩点后建图
void add_c(int x, int y) {
    vc[++tc] = y, nc[tc] = hc[x], hc[x] = tc;
}

void tarjan(int x) {
    dfn[x] = low[x] = ++num;
    stack[++top] = x, ins[x] = 1;//标记x点
    for (int i = head[x]; i; i = Next[i])
        //未走过
        if (!dfn[ver[i]]) {
            tarjan(ver[i]);
            //递归更新
            low[x] = min(low[x], low[ver[i]]);
        }
        else if (ins[ver[i]])
            //直接更新
            low[x] = min(low[x], dfn[ver[i]]);
    if (dfn[x] == low[x]) {
        //一个强连通
        cnt++; int y;
        do {
            y = stack[top--], ins[y] = 0;
            //属于哪一个强连通
            c[y] = cnt, scc[cnt].push_back(y);
        } while (x != y);
    }
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y);
    }
    for (int i = 1; i <= n; i++)
        if (!dfn[i]) tarjan(i);
    for (int x = 1; x <= n; x++)
        for (int i = head[x]; i; i = Next[i]) {
            int y = ver[i];
            if (c[x] == c[y]) continue;
            add_c(c[x], c[y]);
        }
}

原文地址:https://www.cnblogs.com/DWVictor/p/11347956.html

时间: 2024-11-06 07:18:44

Tarjan算法求有向图强连通分量并缩点的相关文章

对求有向图强连通分量的tarjan算法原理的一点理解

先简单叙述一下tarjan算法的执行过程(其他诸如伪代码之类的相关细节可以自己网上搜索,这里就不重复贴出了): 用到两类数组: dfs[]:DFS过程中给定节点的深度优先数,即该节点在DFS中被访问的次序 low[]:从给定节点回溯时,节点的low值为从节点在DFS树中的子树中的节点可以回溯到的栈中DFS值最小的节点的dfs值 一个数据结构:栈,用于确定强连通分量 执行过程:对有向图进行深度优先搜索,每抵达一个新节点A就把该节点A入栈,并初始化dfs[A],然后将low[A]初始化为dfs[A]

tarjan模板(缩点,求有向图强连通分量)

具体思路见详解网址:https://www.byvoid.com/blog/scc-tarjan: 然后整理出了这个tarjan模板,具体数组的功能代码都有注释. const int N=100010; struct data { int to,next; } tu[N*2]; int head[N]; int ip; int dfn[N], low[N];///dfn[]表示深搜的步数,low[u]表示u或u的子树能够追溯到的最早的栈中节点的次序号 int sccno[N];///缩点数组,表

Tarjan 算法求强联通分量

转载自:http://blog.csdn.net/xinghongduo/article/details/6195337 还是没懂Tarjan算法的原理.但是感觉.讲的很有道理. 说到以Tarjan命名的算法,我们经常提到的有3个,其中就包括本文所介绍的求强连通分量的Tarjan算法.而提出此算法的普林斯顿大学的Robert E Tarjan教授也是1986年的图灵奖获得者. 首先明确几个概念. 强连通图.在一个强连通图中,任意两个点都通过一定路径互相连通.比如图一是一个强连通图,而图二不是.因

tarjan算法求强联通分量

昨天学到了一个新的算法tarjan算法,感觉最近都没有怎么学习了...(最近有个感悟啊,就是学习一定的通过实践来进步的. 现在才明白为什么高中的时候老师强调一定要刷题,当然刷完题目之后的总结也非常地重要! 这个tarjan算法用来求强联通分量,在网上看了几篇blog,然后做了一个题目,感觉这个算法很nice啊... 如果没有学这个算法, 我肯定会想直接dfs吧orz... dfs看看是不是每个点能到达连通分量的其他点,好像这样非常麻烦啊,还要记录这个点从哪里来的...这样一想,好像直接dfs我做

tarjan算法 求所有联通分量

摘自:https://blog.csdn.net/qq_34374664/article/details/77488976  (感谢) tarjan算法,之所以用DFS就是因为它将每一个强连通分量作为搜索树上的一个子树.而这个图,就是一个完整的搜索树.为了使这颗搜索树在遇到强连通分量的节点的时候能顺利进行.每个点都有两个参数.1,DFN[]作为这个点搜索的次序编号(时间戳),简单来说就是 第几个被搜索到的.%每个点的时间戳都不一样%.2,LOW[]作为每个点在这颗树中的,最小的子树的根,每次保证

[ACM] HDU 1269 迷宫城堡(Tarjan算法求强联通分量)

迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8099    Accepted Submission(s): 3623 Problem Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A

KS求有向图强连通分量模板

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 int n,m; 6 const int maxn=1e5+2; 7 const int maxm=2*maxn; 8 struct nodeg 9 { 10 int to; 11 int nxt; 12 }eg[maxm]; 13 int headg[maxn]; 14 int headgr[maxn]; 15 struct nodegr

HDU 1269 迷宫城堡 tarjan算法求强连通分量

基础模板题,应用tarjan算法求有向图的强连通分量,tarjan在此处的实现方法为:使用栈储存已经访问过的点,当访问的点离开dfs的时候,判断这个点的low值是否等于它的出生日期dfn值,如果相等,那这个点就在一个强连通分量里面,此时从栈中向外取出元素,知道取出的元素与这个点的值相等时结束,我们所有取出的点与这个点在同一个强连通分量里.下面是代码,其实代码里本来不需要id数组记录点属于哪个强连通分量的,因为题目没有做要求,但是为了保留模板完整还是带着了,以供以后复习使用. #include<c

POJ3180(有向图强连通分量结点数&gt;=2的个数)

The Cow Prom Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1451   Accepted: 922 Description The N (2 <= N <= 10,000) cows are so excited: it's prom night! They are dressed in their finest gowns, complete with corsages and new shoes. T