有向图的强联通分量 tarjan

多与DAG上的DP之类的问题一起出现。

using namespace std;

const int MAXE = 300010;
const int MAXP = 100010;

struct N
{
    int v,next;
}edge[MAXE];
int head[MAXP];
int Top;
int ty[MAXP];
int high[MAXP];
int lowlink[MAXP];
int SCCans,dfsclock;
int S[MAXP],STop;

void InitGraph()
{
    SCCans = dfsclock = 0;
    memset(high,0,sizeof(high));
    memset(ty,0,sizeof(ty));
    memset(head,-1,sizeof(head));
    Top = 0;
    STop = 0;
}

void Link(int u,int v)
{
    edge[Top].next = head[u];
    edge[Top].v = v;
    head[u] = Top++;
}

void dfs(int s)
{
    high[s] = lowlink[s] = ++dfsclock;
    S[STop++] = s;
    int i,v;
    for(i = head[s] ; i != -1; i = edge[i].next)
    {
        v = edge[i].v;

        if(high[v] == 0)
        {
            dfs(v);
            lowlink[s] = min(lowlink[s],lowlink[v]);
        }
        else if(ty[v] == 0)
        {
            lowlink[s] = min(lowlink[s],lowlink[v]);
        }
    }

    if(lowlink[s] == high[s])
    {
        SCCans++;
        do
        {
            v = S[--STop];
            ty[v] = SCCans;
        }while(s != v);
    }
}

vector<int> vec[MAXP];

int main()
{
    int n,m,u,v,i,j;

    while(scanf("%d %d",&n,&m) != EOF)
    {
        InitGraph();

        while(m--)
        {
            scanf("%d %d",&u,&v);

            Link(u,v);
        }

        for(i = 1;i <= n; ++i)
            if(ty[i] == 0)
                dfs(i);

        for(i = 1;i <= SCCans; ++i)
            vec[i].clear();

        for(i = 1;i <= n; ++i)
        {
            for(j = head[i];j != -1;j = edge[j].next)
            {
                if(ty[i] != ty[edge[j].v])
                    vec[ty[i]].push_back(ty[edge[j].v]);
            }
        }
    }

    return 0;
}
时间: 2024-10-09 10:22:47

有向图的强联通分量 tarjan的相关文章

有向图的强联通分量

最近学了有向图的强联通分量.有kosaraju算法,不过写着比tarjin麻烦.所以就只记录tarjin算法. 跟求无向图的双连通分量很相似,先贴代码. 1 void dfs(int u){ 2 dfn[u]=low[u]=++clk;//dfn序 3 stk[top++]=u;//压入栈内 4 for(int i=head[u];i;i=edge[i].nxt){ 5 int t=edge[i].to; 6 if(dfn[t]==0){//如果下一个节点是没有访问过的 7 dfs(t); 8

bzoj 2438: [中山市选2011]杀人游戏 (强联通分量 Tarjan)

Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民. 假如查证的对象是杀手, 杀手将会把警察干掉. 现在警察掌握了每一个人认识谁. 每一个人都有可能是杀手,可看作他们是杀手的概率是相同的. 问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多少? Input 第一行有两个整数 N,M. 接下来有 M 行,每行两个整数 x

POJ 3114 Countries in War(强联通分量+Tarjan)

题目链接 题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0. 思路 :强连通分量缩点之后,求最短路.以前写过,总感觉记忆不深,这次自己敲完再写了一遍. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <vector> 5 #include <stack> 6 #include <queue> 7 #inc

hdu 1269 (强联通分量Tarjan入门)

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

Tarjan的强联通分量

求强联通分量有很多种. <C++信息学奥赛一本通>  中讲过一个dfs求强联通分量的算法Kosdaraju,为了骗字数我就待会简单的说说.然而我们这篇文章的主体是Tarjan,所以我肯定说完之后再赞扬一下Tarjan大法好是不是 首先我们讲一下强联通分量 强联通分量指的是图的一个子图.在这个子图中,任意两个节点都可以互相到达.从定义上我们就可以看出是一个有向图来,因为任意一个无向图都符合该定义. 而它的标准定义是:有向图中任意两点都联通的最大子图. 咳咳,首先庆祝一下哈--本人博客的第一张图.

tarjan算法求强联通分量

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

HDU 1269 迷宫城堡 (强联通分量,Tarjan算法)

Problem Description: 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间.Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i. Input: 输入包含多组数据

codevs 2822 爱在心中 tarjan(强联通分量)

2822 爱在心中 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description “每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动.爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home.” 在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况).爱是具有传递性的,即如果A爱B,B爱C,则A也爱C.如果有这样一部分人,他们彼此都相爱,则他们就超越了一

USACO06JAN The Cow Prom /// tarjan求强联通分量 oj24219

题目大意: n个点 m条边的图 求大小大于1的强联通分量的个数 https://www.cnblogs.com/stxy-ferryman/p/7779347.html tarjan求完强联通分量并染色后 计算一下每种颜色的个数 就是每个强联通块的大小 #include <stdio.h> #include <cstring> #include <algorithm> #include <stack> using namespace std; const i