求强连通分量

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<string>
#include<string.h>
using namespace std;
const int maxx = 100010;
int n,m;
vector<int>g[maxx];
vector<int>rg[maxx];
vector<int>vs;
bool vis[maxx];
int cmp[maxx];
void dfs(int v)
{
    vis[v]=true;
    for(int i=0;i<g[v].size();i++)
    {
        if(!vis[g[v][i]]) dfs(g[v][i]);
    }
    vs.push_back(v);
}
void rdfs(int v)
{
    vis[v]=true;
    for(int i=0;i<rg[v].size();i++)
    {
        if(!vis[rg[v][i]]) rdfs(rg[v][i]);
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)&&(n+m)!=0)
    {
        for(int i=0;i<=n;i++)
        {
            g[i].clear();
            rg[i].clear();
        }
        vs.clear();
        for(int i=0;i<m;i++)
        {
            int tmp1,tmp2;
            scanf("%d%d",&tmp1,&tmp2);
            g[tmp1].push_back(tmp2);
            rg[tmp2].push_back(tmp1);

        }
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                dfs(i);
            }
        }
        memset(vis,0,sizeof(vis));
        int k=0;
        for(int i=vs.size()-1;i>-1;i--)
        {
            if(!vis[vs[i]])
            {
                rdfs(vs[i]);
                k++;
            }
        }
        if(k==1) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

先把代码放这,以后有空把学习过程补上。

时间: 2024-10-08 09:48:18

求强连通分量的相关文章

UESTC 901 方老师抢银行 --Tarjan求强连通分量

思路:如果出现了一个强连通分量,那么走到这个点时一定会在强连通分量里的点全部走一遍,这样才能更大.所以我们首先用Tarjan跑一遍求出所有强连通分量,然后将强连通分量缩成点(用到栈)然后就变成了一个DAG(有向无环图),然后跑一遍DFS,不断加上遍历点的权值,如果到了网吧,则更新一遍答案,因为可以出去了. 求强连通分量时,如果low[u] == dfn[u],说明形成了一个新的强连通分量,且根为u.具体求强连通分量见:http://www.cnblogs.com/whatbeg/p/377642

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]时表示已经回溯到最上面的

CCF 高速公路 tarjan求强连通分量

问题描述 某国有n个城市,为了使得城市间的交通更便利,该国国王打算在城市之间修一些高速公路,由于经费限制,国王打算第一阶段先在部分城市之间修一些单向的高速公路. 现在,大臣们帮国王拟了一个修高速公路的计划.看了计划后,国王发现,有些城市之间可以通过高速公路直接(不经过其他城市)或间接(经过一个或多个其他城市)到达,而有的却不能.如果城市A可以通过高速公路到达城市B,而且城市B也可以通过高速公路到达城市A,则这两个城市被称为便利城市对. 国王想知道,在大臣们给他的计划中,有多少个便利城市对. 输入

poj 2186 tarjan求强连通分量

蕾姐讲过的例题..玩了两天后才想起来做 貌似省赛之后确实变得好懒了...再努力两天就可以去北京玩了! 顺便借这个题记录一下求强连通分量的算法 1 只需要一次dfs 依靠stack来实现的tarjan算法 每次走到一个点 马上把它压入栈中 每次对与这个点相连的点处理完毕 判断是否low[u]==dfn[u] 若是 开始退栈 直到栈顶元素等于u才退出(当栈顶元素等于u也需要pop) 每次一起退栈的点属于同一个强连通分量 储存图可以用链式前向星也可以用邻接矩阵更可以用vector 蕾姐说不会超时 我信

转 tarjan算法求强连通分量

无意中想起图的强连通分量来,之前也一直想写所以今天决定来填这个坑.PS:由于本人比较懒,之前做过一个讲解的PPT,不过那是好遥远之前,年代已久早已失传,所以本文里的图来自网络.以后周末都用来填坑也挺好. ------------------------------分割线----------------------------------------- 在有向图G中,如果两个顶点间至少存在一条路径,那么这两个顶点就是强连通(strongly connected). 如果有向图G的每两个顶点都强连通

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.

hdu 1269 tarjan求强连通分量

tarjan求强连通分量的裸题复习,直接上代码: 1 #include <stack> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int N = 10001; 7 const int M = 100000; 8 int dfn[N], low[N], head[N]; 9 bool inStack[N]; 10 int n, m, e, cnt, dfs_clock

poj1236 Network of Schools ,求强连通分量(Tarjan算法),缩点

题目链接: 点击打开链接 题意: 给定一个有向图,求: 1) 至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点 2) 至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点 顶点数<= 100 求完强连通分量后,缩点,计算每个点的入度,出度. 第一问的答案就是入度为零的点的个数, 第二问就是max(n,m) // 入度为零的个数为n, 出度为零的个数为m. //kuangbin巨巨分析很棒! #include<cstdio> #include<cstring>

图论算法(6)(更新版) --- Tarjan算法求强连通分量

之前Tarjan算法求强连通分量博文中,代码实现用到了固定大小数组,扩展起来似乎并不是很方便,在java里这样来实现本身就是不太妥当的,所以下面给出一个更新版本的代码实现: package test; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util

Tarjan求强连通分量、求桥和割点模板

Tarjan 求强连通分量模板.参考博客 #include<stdio.h> #include<stack> #include<algorithm> using namespace std; const int maxn = 1e3 + 10; const int maxm = 330000 + 10; struct EDGE{ int v, nxt; }Edge[maxm]; int Head[maxn], cnt; int DFN[maxn], LOW[maxn],