POJ 2553 The Bottom of a Graph Tarjan找环缩点(题解解释输入)
Description
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 in G 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 v, v 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
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
line.

Sample Input
3 3
1 3 2 3 3 1
2 1
1 2
0
Sample Output
1 3
2
定义:点v是汇点须满足 --- 对图中任意点u,若v可以到达u则必有u到v的路径;若v不可以到达u,则u到v的路径可有可无。
题意:在n个点m条边的有向图里面,问有多少个点是汇点。
解释一下输入:分别是V顶点数,E边数,下一行每两个点是一条边的出入点。 思路:很明显的Tarjan缩点,满足题意的汇点就是缩点以后出度为0的点。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 5e3+;
int stack[maxn],dfn[maxn],low[maxn],head[maxn],dfs_num,top;
int color[maxn],col_num,in[maxn],out[maxn],mm[maxn],a[maxn];
bool vis[maxn];
class edge
{
public:
int to,next;
}e[maxn*maxn];
inline int gmin(int a,int b)
{
return a<b?a:b;
}
void Tarjan ( int x ) {
dfn[ x ] = ++dfs_num ;
low[ x ] = dfs_num ;
vis [ x ] = true ;//是否在栈中
stack [ ++top ] = x ;
for ( int i=head[ x ] ; i!= ; i=e[i].next ){
int temp = e[ i ].to ;
if ( !dfn[ temp ] ){
Tarjan ( temp ) ;
low[ x ] = gmin ( low[ x ] , low[ temp ] ) ;
}
else if ( vis[ temp ])low[ x ] = gmin ( low[ x ] , dfn[ temp ] ) ;
}
if ( dfn[ x ]==low[ x ] ) {//构成强连通分量
vis[ x ] = false ;
color[ x ] = ++col_num ;//染色
while ( stack[ top ] != x ) {//清空
color [stack[ top ]] = col_num ;
vis [ stack[ top-- ] ] = false ;
}
top -- ;
}
} int main()
{
int n,m;
while(scanf("%d",&n)){
if(!n)break;
scanf("%d",&m);
col_num=dfs_num=top=;
for(int i=;i<=n;i++)
head[i]=in[i]=out[i]=dfn[i]=;
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
e[i].next=head[x];
e[i].to=y;
head[x]=i;
}
for(int i=;i<=n;i++)if(!dfn[i])Tarjan(i);
for(int i=;i<=n;i++)
{
for(int j=head[i];j;j=e[j].next)
{
int t=e[j].to;
if(color[i]!=color[t])
{
out[color[i]]++;
in[color[t]]++;
}
}
}
int k=,ans=;
for(int i=;i<=col_num;i++)
if(!out[i])mm[++k]=i;
for(int i=;i<=k;i++)
for(int j=;j<=n;j++)
if(mm[i]==color[j])a[++ans]=j;
sort(a+,a+ans+);
//printf("%d %d %d\n",k,ans,col_num);忘记初始化 debug多组样例一直过不了而加的..
for(int i=;i<=ans;i++)
printf("%d%c",a[i],i!=ans?' ':'\n');
}
return ;
}
POJ 2553 The Bottom of a Graph Tarjan找环缩点(题解解释输入)的更多相关文章
- POJ 2553 The Bottom of a Graph (Tarjan)
The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 11981 Accepted: ...
- POJ 2553 The Bottom of a Graph TarJan算法题解
本题分两步: 1 使用Tarjan算法求全部最大子强连通图.而且标志出来 2 然后遍历这些节点看是否有出射的边,没有的顶点所在的子强连通图的全部点,都是解集. Tarjan算法就是模板算法了. 这里使 ...
- [poj 2553]The Bottom of a Graph[Tarjan强连通分量]
题意: 求出度为0的强连通分量. 思路: 缩点 具体有两种实现: 1.遍历所有边, 边的两端点不在同一强连通分量的话, 将出发点所在强连通分量出度+1. #include <cstdio> ...
- poj 2553 The Bottom of a Graph(强连通、缩点、出入度)
题意:给出一个有向图G,寻找所有的sink点.“sink”的定义为:{v∈V|∀w∈V:(v→w)⇒(w→v)},对于一个点v,所有能到达的所有节点w,都能够回到v,这样的点v称为sink. 分析:由 ...
- POJ 2553 The Bottom of a Graph(强连通分量)
POJ 2553 The Bottom of a Graph 题目链接 题意:给定一个有向图,求出度为0的强连通分量 思路:缩点搞就可以 代码: #include <cstdio> #in ...
- poj 2553 The Bottom of a Graph(强连通分量+缩点)
题目地址:http://poj.org/problem?id=2553 The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K ...
- poj 2553 The Bottom of a Graph【强连通分量求汇点个数】
The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9641 Accepted: ...
- POJ 2553 The Bottom of a Graph (强连通分量)
题目地址:POJ 2553 题目意思不好理解.题意是:G图中从v可达的全部点w,也都能够达到v,这种v称为sink.然后升序输出全部的sink. 对于一个强连通分量来说,全部的点都符合这一条件,可是假 ...
- poj 2553 The Bottom of a Graph : tarjan O(n) 存环中的点
/** problem: http://poj.org/problem?id=2553 将所有出度为0环中的点排序输出即可. **/ #include<stdio.h> #include& ...
随机推荐
- ZJNU 1067 - 约瑟夫——中级
打表处理(否则Case 1超时) 对m进行枚举,每次枚举进行一次判断 因为好人坏人均为k个,那么只要让下一个死亡的人的位置p保证在1~剩余坏人数量之间即可,不满足则直接break枚举下一个m 实际上对 ...
- ES6之对象的语法糖
本文介绍下ES6中对象的一些拓展功能. 这三个语法糖在实际的项目开发中经常会见到.
- Djang_框架
- 通过特殊处理 Resize 事件解决 WinForm 加载时闪烁问题的一个方法
WinForm 上放置的控件多了或者有大背景图,窗体加载时就会闪烁,对于一般的闪烁,设置 DoubleBuffer=True或许有一点改善,要立竿见影的解决可以重载 CreateParams 使用 W ...
- << 和>> 的计算公式
在java中,一个数左移n位,就是将这个数乘以2的n次方,右移就是将这个数除以2的n次方. 如: 8>>2 = 2 (8/2^2) 15 << 3 = 120 (15*(2 ...
- 吴裕雄--天生自然C语言开发:指针
#include <stdio.h> int main () { int var1; ]; printf("var1 变量的地址: %p\n", &var1 ) ...
- 传输层TCP和UDP
TCP协议 传输控制协议 TCP是面向连接.可靠的进程到进程通信的协议 TCP提供全双工工服务,即数据可在同一时间双向传输 三次握手: ...
- n的m划分
n的m划分: dp[i][j]表示j的i划分,也就是将j颗球放入i个袋子里面,最后的答案是dp[m][n] 状态转移方程为dp[i][j]=dp[i-1][j]+dp[i][j-i]; 划分方法有两种 ...
- VBA编程常用词汇英汉对照表
表 20‑1到表 20‑8是VBA编程中使用频率最高的英文单词,按字母排序.词性列中,a表示形容词,n表示名词,v表示动词,p表示介词以及其他词性. 表 20‑1 VBA编程常用词汇表 单词 中文 词 ...
- VirtualBox虚拟机Ubuntu设置共享文件夹,并自动挂载
一.环境 Win10系统,VirtualBox-5.1.22-115126+Ubuntu16.04(64位)虚拟机 二.目的 在Ubuntu中能够共享Win10中的某个文件夹,而且能够自动挂载 ...