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. Android配置----Android开发环境搭建

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  2. python playfair

    #########################Playfair密码######################### #约定1:若明文字母数量为奇数,在明文末尾添加一个'Z' #约定2:'I'作为 ...

  3. *.location.href 用法:

    *.location.href 用法: top.location.href=”url”          在顶层页面打开url(跳出框架) self.location.href=”url”       ...

  4. spring核心组件

    spring的对象是bean组件,就像面向对象的object,bean包装的是object.context的作用,发现每个bean之间的关系,为他们之间建立好这种关系并进行维护.所以,可以把conte ...

  5. DotNet二维码操作组件ThoughtWorks.QRCode

    DotNet二维码操作组件ThoughtWorks.QRCode 在生活中有一种东西几乎已经快要成为我们的另一个电子"身份证",那就是二维码.无论是在软件开发的过程中,还是在普通用 ...

  6. Linux中查看各文件夹大小命令du -h --max-depth=1

    http://blog.csdn.net/ouyang_peng/article/details/10414499 du -h --max-depth=1  

  7. LinkedList方法总结 ListIterator和Iterator的区别

    LinkedList也像ArrayList一样实现了基本的接口,但是它执行某些从操作时比ArrayList更高效,但在随机访问方面要逊色一些.LinkedList中有一些方法虽然名字不同,但可以完成相 ...

  8. [转]面向GPU的多LOD因子的大规模场景可视化策略

    直接附上原文链接: 1.面向GPU的多LOD因子的大规模场景可视化策略 2.Real-Time Dynamic Level of Detail Terrain Rendering with ROAM

  9. (OAF)jdeveloper集成log4j并将日志输出到指定文件并写入数据库

    参考: How to configure Log4j in JDev 11g Ever wanted to use log4j in your adf project ? Well though Or ...

  10. 34-php基础:cookie

    <?php //1.创建cookie //创建cookie,如下设置,cookie的过期时间为会话结束时 setcookie("name","gaoxiong&qu ...