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. Trie树-可持久化

    // Made by xiper // updata time : 2015 / 12 / 8 // test status: √ // 使用前调用初始化函数 init() 同时 root[0] = ...

  2. CSS3属性选择器与(:not)选择器

    一:css3属性选择器: img[alt]{ border:2px dashed #000; } 这个选择器会匹配页面标签中任何一个含有alt属性的图片标签.   还可以通过设定属性值来缩小匹配范围: ...

  3. iscroll.js的使用

    入门 Scroll是一个类,每个需要使用滚动功能的区域均要进行初始化.每个页面上的iScroll实例数目在设备的CPU和内存能承受的范围内是没有限制的. 尽可能保持DOM结构的简洁.iScroll使用 ...

  4. POJ 3304 Segments【叉积】

    题意:有n条线段,问有没有一条直线使得所有线段在这条直线上的投影至少有一个共同点. 思路:逆向思维,很明显这个问题可以转化为是否有一条直线穿过所有线段,若有,问题要求的直线与该直线垂直,并且公共点为垂 ...

  5. CSU 1116 Kingdoms

    题意:给你n个城市,m条被摧毁的道路,每条道路修复需要c元,总共有k元,给你每个城市的人口,问在总费用不超过k的情况下 与1号城市相连的城市的最大总人口(包括1号城市) 思路:1号城市是必取的,剩余最 ...

  6. 用CSS3实现上下左右箭头

    225deg 向上箭头 135deg向下箭头45deg向右箭头 -45deg向左箭头

  7. Cursor的各种效果

    总结之后的Cursor的各种效果: http://sandbox.runjs.cn/show/bbwoyn0c http://css-cursor.techstream.org/ 源代码如下: < ...

  8. [MySQL] 按日期进行统计(前一天、本周、某一天)

    在mysql数据库中,常常会遇到统计当天的内容.例如,在user表中,日期字段为:log_time统计当天 sql语句为: select * from user where date(log_time ...

  9. 学习bash

    工作8年,前6年基本是Windows环境下,也就是个鼠标党:两年前换工作开始用linux,也就开始了领略了命令行的强大,无论是直接在命令行组合命令,也还写几行简单的shell脚本,其能完成的功能往往令 ...

  10. EF实体框架之CodeFirst五

    上一博客学习了下基本的约定配置,留下几个遗漏的,这篇就是学习下遗漏一复杂类型. 一.什么是复杂类型? 书中说道:“复杂类型也可视作值类型(?)可以作为附加属性添加到其他类.复杂类型与实体类型的区别在于 ...