强连通分量算法模板

  

const int max_v = 120;

struct Scc
{
    int V;           //图的顶点数
    vector<int> G[max_v];    //原始图
    vector<int> rG[max_v];   //反向边的图
    vector<int> vs;          //后序遍历顶点列表
    bool used[max_v];        //访问标记
    int cmp[max_v];          //所属强连通分量的拓扑排序
    void init()
    {
        for(int i=0; i<=V; i++) G[i].clear(), rG[i].clear();
    }
    void add_edge(int from, int to)
    {
        G[from].push_back(to);
        rG[to].push_back(from);
    }
    void dfs(int v)
    {
        used[v] = true;
        for(int i=0; i<G[v].size(); i++)
            if(!used[G[v][i]]) dfs(G[v][i]);
        vs.push_back(v);
    }
    void rdfs(int v, int k)
    {
        used[v] = true;
        cmp[v] = k;
        for(int i=0; i<rG[v].size(); i++)
            if(!used[rG[v][i]]) rdfs(rG[v][i], k);
    }
    int scc()
    {
        memset(used, 0, sizeof(used));
        vs.clear();
        for(int v=1; v<=V; v++)
            if(!used[v]) dfs(v);
        memset(used, 0, sizeof(used));
        int k = 1;
        for(int i=vs.size()-1; i>=0; i--)
            if(!used[vs[i]]) rdfs(vs[i], k++);
        return k-1;
    }
}ss;

使用的时候 ss.v= 7;

ss.init();

ss.add_edge() ..

ss.scc();

时间: 2025-01-05 18:47:42

强连通分量算法模板的相关文章

强连通分量tarjan模板复习

对于一个有向图定点的子集,在该子集中任取两点u与v,都能找到一条从u到v的路径,则称该子集是强连通的.若该集合加入到任意点集中,它都不再强连通,则称这个子集是原图的一个强连通分量.任意一张图都可以分解成若干个不相交的强连通分量.这是强连通分量分解.把分解后的强连通分量缩成一个顶点,就可以得到一个有向无环图. 如图: 求一张图的强连通分量的个数,常用tarjan算法,它是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈

强连通分量算法&#183;$tarjan$初探

嗯,今天好不容易把鸽了好久的缩点给弄完了--感觉好像--很简单? 算法的目的,其实就是在有向图上,把一个强连通分量缩成一个点--然后我们再对此搞搞事情,\(over\) 哦对,时间复杂度很显然是\(\Theta(n)\)的,懒得\(Proof\)了. 真是简明扼要的算法啊\(233\) 比较弱智的代码是下面的: #include <stack> #include <cstdio> #include <iostream> #define min Min #define m

tarjan求强连通分量(模板)

https://www.luogu.org/problem/P2341 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=50010; int pre[maxn],other[maxn],last[maxn],l; int n,m; int dfn[maxn],low[maxn],ans[maxn],st[maxn],belong[maxn

图论算法之(强连通分量&lt;Kosaraju&gt;)

强连通分量算法有3个之多,现在介绍这种名字叫做kosaraju算法. 这个算法基于两个事实,1.原图G与逆置图GT拥有相同的强连通分量,这肯定是正确的 2.任意一个子节点存放皆后于父节点,也就是说所有只有当所有子节点都入栈了,父节点才入栈 这种在递归调用之后将顶点入队列的方式叫逆后续排序(reverse post),在无环图中这种排序方式就是拓扑排序. 简要证明: 1. 第一次DFS有向图G时,最后记录下的节点必为最后一棵生成树的根节点. 证明:假设最后记录下节点不是树根,则必存在一节点为树根,

Tarjan算法分解强连通分量(附详细参考文章)

Tarjan算法分解强连通分量 算法思路: 算法通过dfs遍历整个连通分量,并在遍历过程中给每个点打上两个记号:一个是时间戳,即首次访问到节点i的时刻,另一个是节点u的某一个祖先被访问的最早时刻. 时间戳用DFN数组存储,最早祖先用low数组来存,每次dfs遍历到一个节点u,即让这两个记号等于当前时刻,在后面回溯或者判断的过程中在来更新low,DNF是一定的,因为第一次访问时刻一定.然后遍历u的子节点,也就是跟u相连的点v,依次看子节点的时间戳有没有打上,也就是看他有没有被访问过.\(1\).没

tarjan算法——强连通分量

简述: 用dfn作为时间戳,对图进行dfs并对路径上的点入栈,求出每个点可以访问到的最早的时间戳,此时栈中从这个点开始的点便为一个强连通分量. 模板: 1 void tarjan(int x,int lay,int &sccnum) { 2 low[x]=lay; 3 dfn[x]=lay; 4 vis[x]=1; 5 sta[++cnt]=x; 6 for(int i=head[x];~i;i=e[i].net) { 7 int v=e[i].v; 8 if(!vis[v]) tarjan(v

浅析强连通分量(Tarjan和kosaraju)

理解   在有向图G中,如果两点互相可达,则称这两个点强连通,如果G中任意两点互相可达,则称G是强连通图. 定理: 1.一个有向图是强连通的,当且仅当G中有一个回路,它至少包含每个节点一次.             2.非强连通有向图的极大强连通子图,称为强连通分量(SCC即Strongly Connected Componenet). 在上图中,{1,2,3,4}是一个强连通分量,{5},{6}分别是另外两个强连通分量.怎么判断一个图是否是强连通图,如果不是,有哪些强连通分量,又怎么使它成为强

POJ-3180 The Cow Prom(tarjan求强连通分量)

题目链接:http://poj.org/problem?id=3180 题目大意:求一个有向图的强连通分量 算法:求强连通分量首选tarjan算法 这里简单说一下tarjan的思路 时间戳是什么:在搜索时访问的最早时间 维护dfn[u]表示u的时间戳 low[u]表示u点所能回到的最早的祖先的时间戳 开一个栈,把搜索的点入栈.搜索时遇到已经搜过的点,取low[u]和dfn[v]的最小值,回溯时取low[u]和low[v]的最小值(标记上传)传到dfn[u]<=low[u]时表示已经回溯到最上面的

UVALive 4262——Trip Planning——————【Tarjan 求强连通分量个数】

Road Networks Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 4262 Description There is a road network comprised by M<tex2html_verbatim_mark> roads and N<tex2html_verbatim_mark> cities.