一、【前言】关于tarjan

tarjan算法是由Robert Tarjan提出的求解有向图强连通分量的算法。

那么问题来了找蓝翔!(划掉)什么是强连通分量?

我们定义:如果两个顶点互相连通(即存在A到B和B到A的通路),则称这两个点强连通。对于一个有向图G,若是G中任意两点都强连通,则称G是一个强连通图。有向图的极大强连通子图,称为该图的强连通分量。

对于下图,{1,2,3,4}、{5}、{6}分别是它的强连通分量。

那么tarjan是如何找到这些强连通分量的呢?

说白了tarjan就是dfs,每个强连通分量都是搜索树中的一颗子树。搜索时,我们把当前搜索树中未处理过的点加入一个堆栈,回溯时从栈顶依次取出元素判断他们是否属于一个强连通分量。

我们对dfs的过程中添加如下定义:
1、dfn[i]:代表搜索点i的次序编号;

2、low[i]:代表点i所能回溯到的栈中最早的次序编号。

当dfn[i]=low[i]时,以i为根的子树上的所有点便构成一个强连通分量。

二、tarjan算法c语言实现

那么要如何使用程序来实现tarjan算法呢?

大致思路如下:
1、从一个未被处理过的点i开始,给它结合一个次序编号并把它压入栈中,然后标记点表示其已入栈,令low[i]=dfn[i]=次序编号;

2、遍历每条以i为起点的边,若边的终点j未被处理过,就对其进行操作1~3,令low[i]=min(low[i],low[j]);

3、找到的点j若是被处理过,则判断其是否在栈中:若在,则令low[i]=min(low[i],dfn[j]);

4、若是dfn[i]=low[i],就将栈顶到i间的所有元素弹出,它们便是一个强连通分量;

5、重复1~4,直至不存在点未被处理。

贴上伪代码(转自百度百科词条——tarjan算法)

 tarjan(u)
{
DFN[u]=Low[u]=++Index//为节点u设定次序编号和Low初值
Stack.push(u)//将节点u压入栈中
for each(u,v) in E//枚举每一条边
if (visnotvisted)//如果节点v未被访问过
tarjan(v)//继续向下找
Low[u]=min(Low[u],Low[v])
else if (vinS)//如果节点v还在栈内
Low[u]=min(Low[u],DFN[v])
if (DFN[u]==Low[u])//如果节点u是强连通分量的根
repeat{
v=S.pop//将v退栈,为该强连通分量中一个顶点
printv
until(u==v)
}

tarjan伪代码

三、codevs1332题解

http://codevs.cn/problem/1332/←_←挂上原题链接

这是一道全♂裸的tarjan题,我们只需跑一遍tarjan,并对所有强连通分量染色,最后输出最大的就好

代码如下:

 #include<stdio.h>
#include<algorithm>
using namespace std;
struct node
{
int v;
int next;
}e[];//邻接表记录有向图
int stack[],top;//栈
int dfn[],low[],index;//index用于记录次序编号
bool vis[];//判断点是否在栈内
int st[],cnt;
int color[],s[],num;//用于染色并记录颜色种类
void build(int a,int b)
{
e[++cnt].v=b;
e[cnt].next=st[a];
st[a]=cnt;
}//建图,没什么好说的
void tarjan(int x)
{
dfn[x]=++index;
low[x]=index;
vis[x]=true;
stack[++top]=x;//当前点入栈
int i;
for(i=st[x];i!=;i=e[i].next)//枚举以当前点为起点的边
{
int temp=e[i].v;//temp为当前被枚举边的终点
if(!dfn[temp])//如果当前边终点未被处理
{
tarjan(temp);
low[x]=min(low[x],low[temp]);
}
else if(vis[temp])low[x]=min(low[x],dfn[temp]);
}
if(dfn[x]==low[x])
{
vis[x]=false;
color[x]=++num;//给当前强连通分量染上新颜色
s[num]++;//给当前强连通分量里的点染色
while(stack[top]!=x)//栈顶元素依次出栈
{
s[num]++;
color[stack[top]]=num;
vis[stack[top--]]=false;
}
top--;
}
}
int main()
{
int n,m,i,a,b,t,ans=,f;
scanf("%d%d",&n,&m);
for(i=;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&t);
build(a,b);
if(t-)build(b,a);
}
for(i=;i<=n;i++)
{
if(!dfn[i])tarjan(i);
}
for(i=;i<=n;i++)
{
if(s[color[i]]>ans)//找到被染色最多的强连通分量(因为要求字典序,所以使用'>')
{
ans=s[color[i]];
f=i;
}
}
printf("%d\n",ans);
for(i=;i<=n;i++)
{
if(color[i]==color[f])printf("%d ",i);//输出被染成最大强连通分量的颜色的点
}
return ;
}

codevs1332

弱弱地说一句,本蒟蒻码字也不容易,转载请注明出处http://www.cnblogs.com/Maki-Nishikino/p/5866191.html

【小白入门向】tarjan算法+codevs1332上白泽慧音 题解报告的更多相关文章

  1. [洛谷P1726][codevs1332]上白泽慧音

    题目大意:求一个有向图的最大强连通分量中点的个数,并输出这些点(字典序最小). 解题思路:裸的强连通分量. 数据小,求完强连通分量后排序+vector大小比较即可(vector有小于运算符). C++ ...

  2. 洛谷1726 上白泽慧音 tarjan模板

    题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间 ...

  3. 洛谷P1726 上白泽慧音 [Tarjan]

    题目传送门 上白泽慧音 题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村 ...

  4. 上白泽慧音(tarjan,图的染色)

    题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间 ...

  5. Tarjan缩点【p1726】上白泽慧音

    Description 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的 ...

  6. 洛谷P1726 上白泽慧音(Tarjan强连通分量)

    P1726 上白泽慧音 题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村 ...

  7. P1726 上白泽慧音 tarjan 模板

    P1726 上白泽慧音 这是一道用tarjan做的模板,要求找到有向图中最大的联通块. #include <algorithm> #include <iterator> #in ...

  8. P1726 上白泽慧音

    题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间 ...

  9. 洛谷P1726 上白泽慧音

    题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间 ...

随机推荐

  1. 使用javascript实现在页面打印的效果的三种方式

    <div id="console"></div> <script type="text/javascript"> var c ...

  2. EL表达式与JSTL

    内容包括 EL表达式 EL函数库 JSTL 核心标签库 格式化标签库 SQL标签库 XML标签库 自定义标签库 EL表达式 EL是Expression Language的是缩写,是JSP页面编写的一种 ...

  3. ios-实现项目在开发、测试、正式环境快速部署

    快速部署:简单的来说,就是不用更改开发.测试.正式环境下的 url ,来实现在同一台测试手机快速部署三种项目状态. Bundle ID一样只会出现一个app:不一样会出现三个app: 具体步骤: 一. ...

  4. 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解

    Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解   多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...

  5. 使用DB4o做一个.Net版的website(一)环境

    一个机缘巧合之下,知道了DB4o这个数据库引擎,下载查看之后,被其方便.高效.以及便捷的管理方式锁折服. 故决定使用其做一个.NET版本的web站点,来巩固学到的知识,以及为后来人做一点点贡献. 首先 ...

  6. JBoss和Tomcat版本、及Servlet、JSP规范版本对应一览 【转】

    原文地址:http://blog.csdn.net/hills/article/details/40896357 JBoss和Tomcat版本.及Servlet.JSP规范版本对应一览 JBossAS ...

  7. Linux内核设计第二周——操作系统工作原理

    Linux内核设计第二周 ——操作系统工作原理 作者:宋宸宁(20135315) 一.实验过程 图1 执行效果 从图中可以看出,每执行my_ start_ kernel函数两次或一次,my_ time ...

  8. 使用Visual Studio 2015开发Android 程序

    环境配置: 操作系统:win 7 64位 IDE:Visual Studio 2015 SDK:installer_r24.3.3-windows 安装前提: 编辑hosts文件(在附件可下载)因为安 ...

  9. oracle:case when 语句的区间用法

    在练习case when 语句时,碰到一个例子,结果答案根本就不对,语法就通不过,开始想着是不是case 只能是一个固定的取值,毕竟例子内给的都是case是个固定的值,后来网上查了好久才发现还有区间的 ...

  10. ssm框架中的struts我的配置问题

    <?xml version="1.0" encoding="UTF-8" ?>  <!DOCTYPE struts PUBLIC    &qu ...