SCC即强连通分量,即一个图的子图,其中的点能相互到达,全称是strongly connected component。

Tarjan算法是用来找出图的SCC。

伪代码

int index = ;  //全局变量i
stack s; //全局堆栈s
void tarjan(vertex v){
LOW[v] = DFN[v] = ++index; //初始化LOW和DFN
s.push(v);
for(所有与v相连的节点w){
if(w没有被访问过){
//(v, w)是搜索树上的边
tarjan(w);
LOW[v] = min(LOW[v], LOW[w]);
}
else if(DFN[w] < DFN[v]){
//(v, w)是交叉边或后向边,判断剔除了无用的前向边
if(w in s)
LOW[v] = min(LOW[v], DFN[w])
}
}
if(DFN[v] == LOW[v]){
while(s.top() >= v){
//移除栈内元素直到v,构成一个强连通分量
//
s.pop();
}
}
}

  

实际上LOW[v] = min(LOW[v], DFN[w])这句可以写成LOW[v] = min(LOW[v], LOW[w]),只要保证LOW[v]比DFN[v]小就可以。

题目

POJ 2186 Popular Cows

找出受所有人欢迎的奶牛,用tarjan缩点,缩点后的图里如果只有一个出度为0,那就把该缩点包含的点的个数输出,否则输出0。

#include <cstdio>
#include <cstring>
#include <stack>
#include<vector>
using namespace std;
const int N = ;
const int M = ;
struct data
{
int to,next;
} tu[M];
int head[N],ip;
int dfn[N],low[N];//dfn[]表示深搜的步数,low[u]表示u或u的子树能够追溯到的最早的栈中节点的次序号
int sccno[N];//缩点数组,表示某个点对应的缩点值
int cnt[N];//这个缩点有几个点组成
int step;
int scc_cnt;//强连通分量个数
int o[N];
int n,m,num,ans;
void init()
{
memset(head,-,sizeof head);
scanf("%d%d",&n,&m);
for(int i=; i<=m; i++)
{
int u,v;
scanf("%d%d",&u,&v);
tu[ip].to=v,tu[ip].next=head[u],head[u]=ip++;
}
}
stack<int> S;
void dfs(int u)
{
dfn[u]=low[u]=++step;
S.push(u);
for(int i=head[u]; i!=-; i=tu[i].next)
{
int v=tu[i].to;
if(!dfn[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(!sccno[v])
low[u]=min(low[u],low[v]);
}
if(low[u]==dfn[u])
{
scc_cnt++;
while()
{
int x=S.top();
S.pop();
sccno[x]=scc_cnt;
cnt[scc_cnt]++;
if(x==u)break;
}
}
}
void solve()
{
for(int u=; u<=n; u++)
for(int i=head[u]; i!=-; i=tu[i].next)
{
int v=tu[i].to;
if(sccno[u]!=sccno[v]){
o[sccno[u]]++;
break;
}
}
for(int i=; i<=scc_cnt; i++)
if(o[i]==)
{
ans=i;
num++;
if(num>)break;
}
if(num==)
ans= cnt[ans];
else ans=;
}
int main()
{
//freopen("in.txt","r",stdin);
init();
for(int i=; i<=n; i++)
if(!dfn[i])dfs(i);
solve();
printf("%d\n",ans);
return ;
}

  

Tarjan算法的更多相关文章

  1. 有向图强连通分量的Tarjan算法

    有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...

  2. 点/边 双连通分量---Tarjan算法

    运用Tarjan算法,求解图的点/边双连通分量. 1.点双连通分量[块] 割点可以存在多个块中,每个块包含当前节点u,分量以边的形式输出比较有意义. typedef struct{ //栈结点结构 保 ...

  3. 割点和桥---Tarjan算法

    使用Tarjan算法求解图的割点和桥. 1.割点 主要的算法结构就是DFS,一个点是割点,当且仅当以下两种情况:         (1)该节点是根节点,且有两棵以上的子树;         (2)该节 ...

  4. Tarjan算法---强联通分量

    1.基础知识 在有向图G,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子 ...

  5. (转载)LCA问题的Tarjan算法

    转载自:Click Here LCA问题(Lowest Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两 ...

  6. 强连通分量的Tarjan算法

    资料参考 Tarjan算法寻找有向图的强连通分量 基于强联通的tarjan算法详解 有向图强连通分量的Tarjan算法 处理SCC(强连通分量问题)的Tarjan算法 强连通分量的三种算法分析 Tar ...

  7. [知识点]Tarjan算法

    // 此博文为迁移而来,写于2015年4月14日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vxnx.html UPD ...

  8. Tarjan 算法&模板

    Tarjan 算法 一.算法简介 Tarjan 算法一种由Robert Tarjan提出的求解有向图强连通分量的算法,它能做到线性时间的复杂度. 我们定义: 如果两个顶点可以相互通达,则称两个顶点强连 ...

  9. 【小白入门向】tarjan算法+codevs1332上白泽慧音 题解报告

    一.[前言]关于tarjan tarjan算法是由Robert Tarjan提出的求解有向图强连通分量的算法. 那么问题来了找蓝翔!(划掉)什么是强连通分量? 我们定义:如果两个顶点互相连通(即存在A ...

  10. 有向图强连通分量 Tarjan算法

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...

随机推荐

  1. Matlab手册翻译

    MATLAB 语言是一种工程语言,语法很像 VB 和 C,比 R 语言容易学,你知道 R 语言的语法有多糟糕么.同样,相对于 Python,MATLAB 的优点是天生为了算而算,数与数之间的运算就是矩 ...

  2. 2014 Super Training #7 C Diablo III --背包问题(DP)

    原题: ZOJ 3769 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769 一个带有一些限制的背包问题. 假设在没有限 ...

  3. Socket Programming in C#--Multiple Sockets

    Now lets say you have two sockets connecting to either two different servers or same server (which i ...

  4. [CareerCup] 8.3 Musical Jukebox 点唱机

    8.3 Design a musical jukebox using object-oriented principles. CareerCup这书实在是太不负责任了,就写了个半调子的程序,说是完整版 ...

  5. 动画:UIKitAnimation 简单动画学习 iOS (一) 渐变 、 移动 、翻页、来回翻转 ——转载

    转载请说明(谢谢) http://blog.csdn.net/a21064346/article/details/7851695 点击打开链接 以下 一个系列的 动画效果 在 UIView.h文件中可 ...

  6. [译]Canvas的基本用法

    在本文章中 <canvas> 元素 替换内容 </canvas> 标签不可省 渲染上下文(The rendering context如何翻译) 检查支持性 一个模板骨架 一个简 ...

  7. Jenkins进阶系列之——01使用email-ext替换Jenkins的默认邮件通知

    1 简述 众所周知,Jenkins默认提供了一个邮件通知,能在构建失败.构建不稳定等状态后发送邮件.但是它本身有很多局限性,比如它的邮件通知无法提供详细的邮件内容.无法定义发送邮件的格式.无法定义灵活 ...

  8. 我是怎么开发一个小型java在线学习网站的

    2016/1/27 11:55:14 我是怎么开发一个小型java在线学习网站的 一直想做一个自己的网站(非博客),但是又不知道做什么内容的好,又一次看到了w3schools,就萌发了开发一个在线ja ...

  9. #Linux学习笔记# 自定义shell终端提示符

    我使用的Linux发行版是LinuxMint 17.2 Rafaela,默认情况下Terminal中的shell提示包括了用户名.主机名.当前目录(绝对路径)和提示符.这样会导致当进入一个比较深的目录 ...

  10. 【niubi-job——一个分布式的任务调度框架】----安装教程

    niubi-job是什么 niubi-job是LZ耗时三个星期,费尽心血打造的一个具备高可靠性以及水平扩展能力的分布式任务调度框架,采用quartz作为底层的任务调度管理器,zookeeper做集群的 ...