这是一道模版题

题目

#define  _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define M 100010
void init();
void build(int u,int v);
void solve(int n);
void tarjan(int v);
struct tt
{
int num,next;
}edge[M];
int dfn[M],low[M],first[M],instack[M],stack[M],index,top,lin,sum; void init()
{
index=top=lin=sum=;
memset(dfn,,sizeof(dfn));
memset(first,-,sizeof(first));
} void build(int u,int v)
{
edge[lin].num=v;
edge[lin].next=first[u];
first[u]=lin++;
} void solve(int n)
{
int i;
for(i=;i<=n;i++)
{
if(dfn[i]==)
tarjan(i);
}
} void tarjan(int v)
{
int t,e;
dfn[v]=low[v]=++index;
instack[v]=;
stack[top++]=v;
for(e=first[v];e!=-;e=edge[e].next)
{
int j=edge[e].num;
if(dfn[j]==)
{
tarjan(j);
if(low[v]>low[j])low[v]=low[j];
}
else if(instack[j]==&&dfn[j]<low[v])
{
low[v]=dfn[j];
}
}
if(dfn[v]==low[v])
{
sum++;
do
{
t=stack[--top];
instack[t]=;
}while(t!=v);
}
} int main()
{
int n,m,i,a,b;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==&&m==)break;
init();
for(i=;i<m;i++)
{
scanf("%d%d",&a,&b);
build(a,b);
} solve(n);
if(sum==) printf("Yes\n");
else printf("No\n");
}
return ;
}

/***************************************************************/

我参考的资料的顺序:

1:学长的ppt里的伪代码:

*tarjan(u)
*{
*    DFN[u]=Low[u]=++Index                      // 为节点u设定次序编号和Low初值
*    Stack.push(u)                              // 将节点u压入栈中
*    for each (u, v) in E                       // 枚举每一条边
*        if (v is not visted)               // 如果节点v未被访问过
*            tarjan(v)                  // 继续向下找
*            Low[u] = min(Low[u], Low[v])
*        else if (v in S)                   // 如果节点v还在栈内
*            Low[u] = min(Low[u], DFN[v])
*    if (DFN[u] == Low[u])                      // 如果节点u是强连通分量的根
*        repeat
*            v = S.pop                  // 将v退栈,为该强连通分量中一个顶点
*            print v
*        until (u== v)
*}
 
2:网上模版
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std; #define MAXN 10010
#define MAXM 100010 struct Edge
{
int v, next;
}edge[MAXM]; //边结点数组 int first[MAXN], stack[MAXN], DFN[MAXN], Low[MAXN], Belong[MAXM];
// first[]头结点数组,stack[]为栈,DFN[]为深搜次序数组,
//Belong[]为每个结点所对应的强连通分量标号数组
// Low[u]为u结点或者u的子树结点所能追溯到的最早栈中结点的次序号
int instack[]; // instack[]为是否在栈中的标记数组
int n, m, cnt, scnt, top, tot; void init()
{
cnt = ;
scnt = top = tot = ;
//初始化连通分量标号,次序计数器,栈顶指针为0
memset(first, -, sizeof(first));
memset(DFN, , sizeof(DFN));
//结点搜索的次序编号数组为0,同时可以当是否访问的数组使用
} void read_graph(int u, int v) //构建邻接表
{
edge[tot].v = v;
edge[tot].next = first[u];
first[u] = tot++;
} void Tarjan(int v) //Tarjan算法求有向图的强连通分量
{
int min, t;
DFN[v] = Low[v] = ++cnt; //cnt为时间戳
instack[v] = ; //标记在栈中
stack[top++] = v; //入栈
for(int e = first[v]; e != -; e = edge[e].next)
{ //枚举v的每一条边
int j = edge[e].v; //v所邻接的边
if(!DFN[j])
{ //未被访问
Tarjan(j); //继续向下找
if(Low[v] > Low[j]) Low[v] = Low[j];
// 更新结点v所能到达的最小次数层
}
else if(instack[j] && DFN[j] < Low[v])
{ //如果j结点在栈内,
Low[v] = DFN[j];
}
}
if(DFN[v] == Low[v])
{ //如果节点v是强连通分量的根
scnt++; //连通分量标号加1
do
{
t = stack[--top]; //退栈
instack[t] = ; //标记不在栈中
Belong[t] = scnt; //出栈结点t属于cnt标号的强连通分量
}while(t != v); //直到将v从栈中退出
}
} void solve()
{
for(int i = ; i <= n; i++) //枚举每个结点,搜索连通分量
if(!DFN[i]) //未被访问
Tarjan(i); //则找i结点的连通分量
} int main()
{
while(scanf("%d%d",&n,&m) && (n || m))
{
init();
while(m--)
{
int u, v;
scanf("%d%d", &u, &v);
read_graph(u, v);
}
solve(); //求强连通分量
if(scnt == ) printf("Yes\n");
//只有一个强连通分量,说明此图各个结点都可达
else printf("No\n");
}
return ;
}
 

hdu 1269 迷宫城堡(强联通分量,基础)的更多相关文章

  1. HDU 1269 迷宫城堡 (强连通分量,常规)

    题意: 判断所给的有向图是否是一个强连通图. 思路: 如果连通分量大于1则必定No,如果强连通分量大于1也是No.tarjan算法求强连通分量. #include <cstdio> #in ...

  2. HDU 1269 迷宫城堡(强连通)

    HDU 1269 迷宫城堡 pid=1269" target="_blank" style="">题目链接 题意:中文题 思路:强连通模板题 代 ...

  3. 【强联通图 | 强联通分量】HDU 1269 迷宫城堡 【Kosaraju或Tarjan算法】

      为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明 ...

  4. HDU 1269 迷宫城堡 【强联通分量(模版题)】

    知识讲解: 在代码里我们是围绕 low 和 dfn 来进行DFS,所以我们务必明白 low 和 dfn 是干什么的? 有什么用,这样才能掌握他.   1.  dfn[]  遍历到这个点的时间 2.   ...

  5. hdu 1269 迷宫城堡

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1269 迷宫城堡 Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个 ...

  6. HDU 1269 迷宫城堡(判断有向图强连通分量的个数,tarjan算法)

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  7. hdu 1269 迷宫城堡 强连通分量

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  8. hdu 1269 迷宫城堡 最简单的联通图题 kosaraju缩点算法

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem Des ...

  9. 迷宫城堡(强联通targin)

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  10. hdu 1269 迷宫城堡(Targin算法)

    ---恢复内容开始--- 迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

随机推荐

  1. Integer类型值相等或不等分析

    看到博客园一位博友写的面试问题,其中一题是 Integer a = 1; Integer b = 1 ; (a == b)?true :false; 当时我一看,这不是明显的true 嘛,  看到评论 ...

  2. java synchronized关键字浅探

    synchronized 是 java 多线程编程中用于使线程之间的操作串行化的关键字.这种措施类似于数据库中使用排他锁实现并发控制,但是有所不同的是,数据库中是对数据对象加锁,而 java 则是对将 ...

  3. c/c++面试总结(2)

    4.深拷贝和浅拷贝 (1)什么时候会用到拷贝函数 一个对象以值传递的方式传入函数(就是作为入参) 一个对象以值传递的方式从函数返回(就是作为返回值) 一个对象需要通过另外一个对象进行初始化 (2)是否 ...

  4. Linux 软中断

    本文转载自: http://blog.chinaunix.net/uid-9620812-id-3833377.html,如有需要,请移步访问. Technorati 标签: Linux 软中断 -- ...

  5. PHP 函数extension_loaded();

    extension_loaded — 检查一个扩展是否已经加载 例如: <?php if (!extension_loaded('gd')) { if (!dl('gd.so')) { exit ...

  6. 例题6-5 Boxes in a line uVa12657

    这道题目的解决方案是双向链表,数据结构本身并不复杂,但对于四种情况的处理不够细致,主要体现在以下几点: 分类讨论不全面,没有考虑特殊情况(本身不需要操作,需要互换的两元素相邻) 没有考虑状态4改变后对 ...

  7. 文件上传下载struts2

    上传方式1: // 保存上传的文件 public boolean saveFile(File file, String fileName) throws IOException { File newF ...

  8. 为ProgressBar进度条设置颜色1

    可以通过xml文件来设置,方法如下: 1:先在布局文件中的ProgressBar加入下面属性: android:progressDrawable="@drawable/progress_ba ...

  9. 【译】Android系统简介

    简介  本文主要介绍Android的基础知识和体系结构,本文主题: 简介什么是Android,为什么开发者需要关注Android: Android体系结构(如Linux Kernel, Librari ...

  10. Mysql 数据分组取某字段值所有最大的记录行

    需求: 表中同一个uid(用户)拥有多条游戏等级记录,现需要取所有用户最高等级(level)的那一条数据,且时间(time)越早排越前.这是典型的排名表 +------+-------+------- ...