http://poj.org/problem?id=2553

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

Description

We will use the following (standard) definitions from graph theory. Let V be a nonempty and finite set, its elements being called vertices (or nodes). Let E be a subset of the Cartesian product V×V, its elements being called edges.
Then G=(V,E) is called a directed graph. 

Let n be a positive integer, and let p=(e1,...,en) be a sequence of length n of edges ei∈E such that ei=(vi,vi+1) for a sequence of vertices (v1,...,vn+1).
Then p is called a path from vertex v1 to vertex vn+1 inG and we say that vn+1 is reachable from v1, writing (v1→vn+1)

Here are some new definitions. A node v in a graph G=(V,E) is called a sink, if for every node w in G that is reachable from vv is also reachable from w. The bottom of a graph is the subset of
all nodes that are sinks, i.e., bottom(G)={v∈V|∀w∈V:(v→w)⇒(w→v)}. You have to calculate the bottom of certain graphs.

Input

The input contains several test cases, each of which corresponds to a directed graph G. Each test case starts with an integer number v, denoting the number of vertices of G=(V,E), where the vertices will be identified by the integer
numbers in the set V={1,...,v}. You may assume that 1<=v<=5000. That is followed by a non-negative integer e and, thereafter, e pairs of vertex identifiers v1,w1,...,ve,we with
the meaning that (vi,wi)∈E. There are no edges other than specified by these pairs. The last test case is followed by a zero.

Output

For each test case output the bottom of the specified graph on a single line. To this end, print the numbers of all nodes that are sinks in sorted order separated by a single space character. If the bottom is empty, print an empty line.

Sample Input

3 3
1 3 2 3 3 1
2 1
1 2
0

Sample Output

1 3
2

求出连通块里的点满足下面条件:所有能到达点v的点w,v也能到达所有的w,因此要求的是联通块,然后缩点,求出度为零的连通块里的点,然后按照升序输出元素;

程序:

#include"stdio.h"
#include"string.h"
#include"queue"
#include"stack"
#include"iostream"
#define M 5009
#define inf 100000000
using namespace std;
struct node
{
int v;
node(int vv)
{
v=vv;
}
};
vector<node>edge[M];
stack<int>q;
int use[M],low[M],dfn[M],belong[M],num,index,in[M],out[M];
void tarjan(int u)
{
dfn[u]=low[u]=++index;
q.push(u);
use[u]=1;
for(int i=0;i<(int)edge[u].size();i++)
{
int v=edge[u][i].v;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(use[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u])
{
num++;
int p;
do
{
p=q.top();
q.pop();
use[p]=0;
belong[p]=num;
}while(p!=u);
}
}
void slove(int n)
{
num=index=0;
memset(use,0,sizeof(use));
memset(dfn,0,sizeof(dfn));
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
}
int main()
{
int n,m,i;
while(scanf("%d",&n),n)
{
scanf("%d",&m);
for(i=1;i<=n;i++)
edge[i].clear();
for(i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
edge[u].push_back(node(v));
}
slove(n);
if(num==1)
{
for(i=1;i<=n;i++)
{
if(i==1)
printf("%d",i);
else
printf(" %d",i);
}
printf("\n");
continue;
}
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
for(int u=1;u<=n;u++)
{
for(int j=0;j<(int)edge[u].size();j++)
{
int v=edge[u][j].v;
if(belong[u]!=belong[v])
{
out[belong[u]]++;
in[belong[v]]++;
}
}
}
int ff=0;
for(i=1;i<=n;i++)
{
if(!out[belong[i]])
{
if(ff==0)
printf("%d",i);
else
printf(" %d",i);
ff++;
}
}
printf("\n");
}
}

强连通分量+缩点(poj2553)的更多相关文章

  1. POJ2553 The Bottom of a Graph(强连通分量+缩点)

    题目是问,一个有向图有多少个点v满足∀w∈V:(v→w)⇒(w→v). 把图的强连通分量缩点,那么答案显然就是所有出度为0的点. 用Tarjan找强连通分量: #include<cstdio&g ...

  2. 【poj2553】The Bottom of a Graph(强连通分量缩点)

    题目链接:http://poj.org/problem?id=2553 [题意] 给n个点m条边构成一幅图,求出所有的sink点并按顺序输出.sink点是指该点能到达的点反过来又能回到该点. [思路] ...

  3. POJ1236Network of Schools[强连通分量|缩点]

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16571   Accepted: 65 ...

  4. POJ1236Network of Schools(强连通分量 + 缩点)

    题目链接Network of Schools 参考斌神博客 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后 ...

  5. HD2767Proving Equivalences(有向图强连通分量+缩点)

    题目链接 题意:有n个节点的图,现在给出了m个边,问最小加多少边是的图是强连通的 分析:首先找到强连通分量,然后把每一个强连通分量缩成一个点,然后就得到了一个DAG.接下来,设有a个节点(每个节点对应 ...

  6. UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)

    题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点. 其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了. 那么问题就简单了, ...

  7. ZOJ3795 Grouping(强连通分量+缩点+记忆化搜索)

    题目给一张有向图,要把点分组,问最少要几个组使得同组内的任意两点不连通. 首先考虑找出强连通分量缩点后形成DAG,强连通分量内的点肯定各自一组,两个强连通分量的拓扑序能确定的也得各自一组. 能在同一组 ...

  8. uva 11324 The Largest Clique(强连通分量缩点+DAG动态规划)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=sh ...

  9. poj 2762 Going from u to v or from v to u?(强连通分量+缩点重构图+拓扑排序)

    http://poj.org/problem?id=2762 Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit:  ...

  10. tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)

    这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...

随机推荐

  1. C++中前置声明的应用与陷阱

    前置声明的使用 有一定C++开发经验的朋友可能会遇到这样的场景:两个类A与B是强耦合关系,类A要引用B的对象,类B也要引用类A的对象.好的,不难,我的第一直觉让我写出这样的代码: // A.h #in ...

  2. e591. Drawing Simple Text

    See also e575 The Quintessential Drawing Program. public void paint(Graphics g) { // Set the desired ...

  3. R语言中两个数组(或向量)的外积怎样计算

    所谓数组(或向量)a和b的外积,指的是a的每个元素和b的每个元素搭配在一起相乘得到的新元素.当然运算规则也可自己定义.外积运算符为 %o%(注意:百分号中间的字母是小写的字母o).比如: > a ...

  4. R语言低级绘图函数-arrows

    arrows 函数用来在一张图表上添加箭头,只需要分别指定起始坐标和终止坐标,就可以添加箭头了,还可以通过一些属性对箭头的形状,大小进行调整 基本用法: xo, yo 指定起始点的x和y坐标,x1, ...

  5. Unity3D-光照贴图技术

    概念 Lightmapping光照贴图技术是一种增强静态场景光照效果的技术,其优点是可以通过较少的性能消耗使静态场景看上去更加真实,丰富,更加具有立体感:缺点是不能用来实时地处理动态光照.当游戏场景包 ...

  6. php一些常规动态设置与获取

    error_reporting(E_ALL); ini_set('display_errors', TRUE); ini_set('display_startup_errors', TRUE);ini ...

  7. PHP curl_setopt函数用法介绍补充篇

    1.curl数据采集系列之单页面采集函数get_html 单页面采集在数据采集过程中是最常用的一个功能 有时在服务器访问限制的情况下 只能使用这种采集方式 慢 但是可以简单的控制 所以写好一个常用的c ...

  8. linux,ubuntu14.04.5下安装搜狗输入法

    参考内容: http://www.linuxidc.com/Linux/2015-03/114347.htm https://jingyan.baidu.com/album/ad310e80ae6d9 ...

  9. js的form表单提交url传参数(包含+等特殊字符)的解决方法

    方法一:(伪装form表单提交) linkredwin = function(A,B,C,D,E,F,G){        var formredwin = document.createElemen ...

  10. 最大子数组之和(N)

    int maxSum(int *array, int n) { ]; ; ; ; i < n; i++) { ) newsum += array[i]; else newsum = array[ ...