算法思路:
  

       这个算法思路不难理解,任何一个强连通分量,必定是对原图的深度优先搜索树的子树。

       那么其实,我们只要确定每个强连通分量的子树的根,然后根据这些根从树的最低层开始,一个一个的拿出强连通分量即可。那么眼下的问题就只

剩下如何确定强连通分量的根和如何从最低层开始拿出强连通分量了。
     

       那么如何确定强连通分量的根,在这里我们维护两个数组,一个是indx[1..n],一个是mlik[1..n],其中indx[i]表示顶点i开始访问时间,mlik[i]为与

顶点i邻接的顶点,未删除顶点j的mlik[j]和mlik[i]的最小值(mlik[i]初始化为indx[i])。这样,在一次深搜的回溯过程中,如果发现mlik[i]==indx[i]那么,

当前顶点就是一个强连通分量的根,为什么呢?因为如果它不是强连通分量的跟,那么它一定是属于另一个强连通分量,而且它的根是当前顶点的祖

宗,那么存在包含当前顶点的到其祖宗的回路,可知mlik[i]一定被更改为一个比indx[i]更小的值。

      至于如何拿出强连通分量,这个其实很简单,如果当前节点为一个强连通分量的根,那么它的强连通分量一定是以该根为根节点的(剩下节点)子

树。在深度优先遍历的时候维护一个堆栈,每次访问一个新节点,就压入堆栈。现在知道如何拿出了强连通分量了吧?是的,因为这个强连通分量时最

先被压人堆栈的,那么当前节点以后压入堆栈的并且仍在堆栈中的节点都属于这个强连通分量。当然有人会问真的吗?假设在当前节点压入堆栈以后压

入并且还存在,同时它不属于该强连通分量,那么它一定属于另一个强连通分量,但当前节点是它的根的祖宗,那么这个强连通分量应该在此之前已经

被拿出。现在没有疑问了吧,那么算法介绍就完了。

题目:Triangle LOVE

题意:给定一个有向图并规定:每两个点之间一定有边,同时A指向B则B定不能指向A,反之亦然。 询问是否存在仅有三个点构成的环。

思路:

首先判断有向图中是否存在环马上有tarjan能够很好的解决。并且如果存在大于三个点以上的环的话肯定存在仅有三个点构成的环。 因为每两

个点之间都有边,并且只有一个给定的指向,画几个图便可以推导出这样的结论。

证明: 假设存在一个n元环,因为a->b有边,b->a必定没边,反之也成立 所以假设有环上三个相邻的点a-> b-> c,那么如果c->a间有边,就已经形

成了一个三元环,如果c->a没边,那么a->c肯定有边,这样就形成了一个n-1元环。。。。 所以只需证明n为4时一定有三元环即可,显然成立。 所

以知道在tarjan后或中判断是否存在大于等于三个点的强连通图。复杂度为边数即O(n*n)。

#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int N=2005;
int head[N],low[N];
int dfn[N],stack[N];
int ans[N];
bool temp[N];
char str[N][N];
int index,m,flag;
typedef struct
{
int to;
int next;
}Node;
Node map[N*N];
void add(int u,int v)
{
map[index].to=v;
map[index].next=head[u];
head[u]=index++;
}
void Tarbfs(int k,int lay,int &scc_num)
{
int t;
temp[k]=1;
low[k]=lay;
dfn[k]=lay;
stack[m++]=k;
for(int i=head[k];i!=-1;i=map[i].next)
{
t=map[i].to;
if(!dfn[t])
{
Tarbfs(t,++lay,scc_num);
if(flag) return;
low[k]=min(low[k],low[t]);
}
if(temp[t])
{
low[k]=min(low[k],dfn[t]);
}
}
if(dfn[k]==low[k])
{
++scc_num;
while(1)
{
t=stack[--m];
temp[t]=0;
ans[scc_num]++;
if(ans[scc_num]>=3)
{
flag=1;
return;
}
if(t==k) break;
}
}
if(flag) return;
}
int Tarjan(int n)
{
int scc_num=0,lay=1;
m=0;
memset(temp,0,sizeof(temp));
memset(low,0,sizeof(low));
for(int i=1;i<=n;i++)
{
if(!dfn[i])
Tarbfs(i,lay,scc_num);
if(flag) break;
}
return scc_num;
}
int main()
{
int i,j,n,t=1,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(dfn,0,sizeof(dfn));
memset(ans,0,sizeof(ans));
memset(head,-1,sizeof(head));
memset(stack,0,sizeof(stack));
index=flag=0;
for(i=1;i<=n;i++)
scanf("%s",str[i]+1);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(str[i][j]=='1')
{
add(i,j);
}
}
}
printf("Case #%d: ",t++);
Tarjan(n);
if(flag)   puts("Yes");
else       puts("No");
}
return 0;
}

HDU4324(强连通的Tarjan算法)相关推荐

  1. 强连通分量(Tarjan算法)和缩点

    强连通分量(Tarjan算法)和缩点 一些定义 给定一张有向图,对于图中任意两个节点 xxx 和 yyy ,存在从 xxx 到 yyy 的路径,也存在从 yyy 到 xxx 的路径,则称该有向图为强连 ...

  2. 强连通分量(Tarjan算法) 图解

    强连通分量(Tarjan算法) 前言 第一件事:没事不要while(m–),会带来不幸 第二件事:看博客先看看评论,如果博主他写错了的话- 简介 先讲几个定义 强连通:两个顶点 uuu,vvv 可以相 ...

  3. 有向图强连通分量tarjan算法

    转自:http://www.byvoid.com/blog/scc-tarjan/ http://blog.csdn.net/geniusluzh/article/details/6601514 在有 ...

  4. 强连通分量——tarjan算法缩点

    一. 什么是强连通分量? 强连通分量:在有向图G中,如果两个顶点u,v间(u->v)有一条从u到v的有向路径,同时还有一条从v到u的有向路径,则称两个顶点强连通(strongly connect ...

  5. 图之强连通、强连通图、强连通分量 Tarjan算法

    一.解释 在有向图G中,如果两个顶点间至少存在一条互相可达路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强 ...

  6. 有向图的强连通分量--Tarjan算法---代码分析

    本文就是做个代码分析,顺便说下理解. 一.预备知识: 需要知道什么是: 回边.前向边.交叉边 二.上代码: #include<algorithm> #define NIL -1using ...

  7. 图论——强连通分量(Tarjan算法)

    文章目录 强连通分量 利用Tarjan算法求强连通分量 来一道例题练手(USACO08DEC) 图论文章汇总 强连通分量 什么是强连通图? 如果一个有向图中,存在一条回路,所有的结点至少被经过一次,这 ...

  8. tarjan算法不是很懂先mark一下。

     前面为转载的.后面是自己的理解. 三种tarjan算法(上) .这篇算是做一个总结吧. 求强连通分量 求无向图的割和桥 最近公共祖先 求强连通分量 基本概念:       强连通是有向图才有的概念. ...

  9. Tarjan算法及其引申

    位于NOI考纲提高组的[7]级算法 [7]求强联通分量算法 [7]强连通分量的缩点算法 [7]求割点.割边算法 认识Tarjan算法 一种由Robert Tarjan提出的求解有向图强连通分量的线性时 ...

最新文章

  1. 《DSP using MATLAB》示例Example7.23
  2. 智能指针_auto_ptr2_学习笔记
  3. ACM模板——并查集
  4. Hadoop Kerberos 认证下 Sentry 安装 + Sentry 权限设置使用
  5. RabbitMQ 下载、安装、配置、验证_rpm版本(Linux环境)
  6. wrong elf class: elfclass32_薇娅倾情推荐亿健ELF跑步机,价格优惠大还为粉丝争取福利! - 消费...
  7. 宝石光是什么石头_沙漠戈壁的漂亮“石头”让人见了流口水
  8. html ajax输出表格中,使用Ajax来渲染HTML表格
  9. 若依如何去掉“正在加载系统资源,请耐心等待”
  10. allavsoft mac版:支持从各种视频分享网站下载视频
  11. 平分物品价值java_网易互联网8.8笔试_第2题平分物品_自己的题解记录
  12. 在水晶报表中插入子报表,并动态添加数据源
  13. 机器学习——下采样(under-sampling)
  14. win10共享计算机win7,win7和win10共享文件怎么设置_win10和win7建立局域网共享操作方法...
  15. 基于javaweb+jsp的户籍管理系统(JavaWeb MySQL JSP Bootstrap Servlet SSM SpringBoot)
  16. 网页设计与制作(HTML+CSS)
  17. 简述java重载和重写的相同点_方法的重载和重写的异同之处
  18. tk域名管理后台_Freenom免费域名.TK、.CF、.ML、.GA注册及使用方法
  19. vim设置(非常全面),即.vimrc文件的配置
  20. 利用电脑学象棋的一点想法

热门文章

  1. 分布式MQ消息存储选择
  2. 任务调度之Quartz1
  3. 封装案例-创建士兵类-完成初始化方法
  4. ElasticSearch 简介,概念和集成
  5. 骁龙660_高通骁龙660可以带动6g运行内存吗?
  6. php如何获取百度快照,PHP获取某网站的百度快照日期方法
  7. undertale人物_「undertale」传说之下精美人物图包 (SansGaster篇)
  8. 搭建卷积神经网络怎么确定参数_AI入门:卷积神经网络
  9. python原生字符串可以参与比较_正则表达式中对于原生字符串的理解
  10. 200901阶段一C++类和对象