本题分两步:

1 使用Tarjan算法求全部最大子强连通图。而且标志出来

2 然后遍历这些节点看是否有出射的边,没有的顶点所在的子强连通图的全部点,都是解集。

Tarjan算法就是模板算法了。

这里使用一个数组和一个标识号,就能够记录这个顶点是属于哪个子强连通图的了。

然后使用DFS递归搜索全部点及其边,假设有边的还有一个顶点不属于本子强连通图。那么就说明有出射的边。

有难度的题目:

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
using namespace std; const int MAX_VEC = 5005;
int n, m;
vector<int> gra[MAX_VEC];
stack<int> stk;
int dfn[MAX_VEC];//tarjan算法记录深度探索得到的标号
int low[MAX_VEC];//tarjan算法记录回溯得到的最低顶点编号
bool inStk[MAX_VEC];//记录是否在栈里面,也能够记录是否被訪问过了
int connectGrp[MAX_VEC];//标志所属的连通子图标号 == connectNum
int vecNum;//顶点标号
int connectNum;//最大强连通子图标号
int out[MAX_VEC];//出度记录 void tarjan(int u)
{
dfn[u] = low[u] = vecNum++;
stk.push(u);
inStk[u] = 1;
for (int i = 0; i < (int)gra[u].size(); i++)
{
int v = gra[u][i];
if (!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);//两处的不同,和含义不同
}
else if (inStk[v]) low[u] = min(dfn[v], low[u]);//两处的不同
}
if (low[u] == dfn[u])
{
++connectNum;
while (stk.size())
{
int v = stk.top(); stk.pop();
inStk[v] = false;
connectGrp[v] = connectNum;
if (u == v) return;
}
}
} void solveConnect()
{
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(inStk, 0, sizeof(inStk));
for (int i = 1; i <= n; i++)
{
if (!dfn[i]) tarjan(i);
}
} void dfsCountOut(int u)
{
inStk[u] = true; //记录是否被訪问过了
for (int i = 0; i < int(gra[u].size()); i++)
{
int v = gra[u][i];
if (connectGrp[u] != connectGrp[v])
{
out[connectGrp[u]]++;//这个组的出度添加; connectGrp[] == connectNum
}
if (!inStk[v]) dfsCountOut(v);//深度优先,不须要使用额外空间
}
} void countConnectOut()
{
memset(inStk, 0, sizeof(inStk)); //这里仅仅记录是否被訪问过的了。
memset(out, 0, sizeof(out));
for (int i = 1; i <= n; i++)
{
if (!inStk[i]) dfsCountOut(i);
}
} int main()
{
int u, v;
while (scanf("%d", &n) && n)
{
connectNum = 0;
vecNum = 1;
scanf("%d", &m);
for (int i = 1; i <= n; i++)
gra[i].clear();
while (stk.size()) stk.pop(); //清零。重中之重 for (int i = 0; i < m; i++)
{
scanf("%d %d", &u, &v);
gra[u].push_back(v); //有向图
} solveConnect();
countConnectOut(); for(int i = 1; i <= n; ++i)
if(out[connectGrp[i]] == 0)
printf("%d ", i);
putchar('\n');
}
return 0;
}

POJ 2553 The Bottom of a Graph TarJan算法题解的更多相关文章

  1. POJ 2553 The Bottom of a Graph (Tarjan)

    The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 11981   Accepted: ...

  2. POJ 2553 The Bottom of a Graph Tarjan找环缩点(题解解释输入)

    Description We will use the following (standard) definitions from graph theory. Let V be a nonempty ...

  3. [poj 2553]The Bottom of a Graph[Tarjan强连通分量]

    题意: 求出度为0的强连通分量. 思路: 缩点 具体有两种实现: 1.遍历所有边, 边的两端点不在同一强连通分量的话, 将出发点所在强连通分量出度+1. #include <cstdio> ...

  4. POJ 2553 The Bottom of a Graph(强连通分量)

    POJ 2553 The Bottom of a Graph 题目链接 题意:给定一个有向图,求出度为0的强连通分量 思路:缩点搞就可以 代码: #include <cstdio> #in ...

  5. poj 2553 The Bottom of a Graph(强连通分量+缩点)

    题目地址:http://poj.org/problem?id=2553 The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K ...

  6. poj 2553 The Bottom of a Graph【强连通分量求汇点个数】

    The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9641   Accepted:  ...

  7. POJ 2553 The Bottom of a Graph (强连通分量)

    题目地址:POJ 2553 题目意思不好理解.题意是:G图中从v可达的全部点w,也都能够达到v,这种v称为sink.然后升序输出全部的sink. 对于一个强连通分量来说,全部的点都符合这一条件,可是假 ...

  8. poj 2553 The Bottom of a Graph : tarjan O(n) 存环中的点

    /** problem: http://poj.org/problem?id=2553 将所有出度为0环中的点排序输出即可. **/ #include<stdio.h> #include& ...

  9. POJ 2553 The Bottom of a Graph 【scc tarjan】

    图论之强连通复习开始- - 题目大意:给你一个有向图,要你求出这样的点集:从这个点出发能到达的点,一定能回到这个点 思路:强连通分量里的显然都可以互相到达 那就一起考虑,缩点后如果一个点有出边,一定不 ...

随机推荐

  1. 获取保存在沙盒中plist文件的用户的字典信息

    获取保存在沙盒中plist文件的用户的字典信息

  2. 3.5MM/2.5MM耳机插头定义

    自2009年国内手机耳机接口统一以来,现在国内销售耳机基本就3.5MM和2.5MM两种,当然也有很少BT厂家,就是不用这两种,比如使用MiniUSB等接口作为耳机接口.3.5mm耳机插头按照结构划分, ...

  3. 手势识别官方教程(4)在挑划或拖动手势后view的滚动用ScrollView和 HorizontalScrollView,自定义用Scroller或OverScroller

    简单滚动用ScrollView和 HorizontalScrollView就够.自定义view时可能要自定义滚动效果,可以使用 Scroller或 OverScroller Animating a S ...

  4. 存储过程系列之存储过程sql数据库调用和程序代码调用

    1.存储过程,无参数的存储过程 创建无参数存储存储过程 Create Procedure DCEMREMR_TEMPLATEAs SELECT TOP 10 [FILENAME],[FILETITLE ...

  5. 【HDOJ】3311 Dig The Wells

    Steiner Tree.概念就不讲了,引入0号结点.[1, n+m]到0连一条边,权重表示挖井的费用.这样建图spfa求MST即满足所求解. /* 3311 */ #include <iost ...

  6. 【原创】MIPS·Verilog·FPGA

    时至今日,终于将全部的计划55条MIPS指令在FPGA上全部验证完毕,通过这近一个月的不断的修改调试.修改调试,我对整个流程对MIPS有了深刻的体会和认识.借着刚刚现阶段任务的兴奋和短暂的空闲时间,将 ...

  7. OSFM Tables

    OSFM - Oracle Shop Floor Management 1. (N) Shop Floor Manager > Lot Based Jobs (B: New) Status: U ...

  8. 函数 flst_get_first

    /********************************************************************//** Gets list first node addre ...

  9. 基于.NET平台的分布式应用程序的研究

    摘 要:.NET框架是Microsoft用于生成分布式Web应用程序和Web服务的下一代平台.概述了用于生成分布式应用程序的.NET框架的基本原理.重点讲述了.NET框架的基础:公共语言运行时(CLR ...

  10. content:attr()

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...