poj 2553 The Bottom of a Graph
2016-09-01 21:11
337 查看
The Bottom of a Graph
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 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
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
Sample Output
Source
Ulm Local 2003
要理解题意,求的是一种点,凡是这种点可以到达的点,都可以返回该点,也就是求出度为0的连通分量中所有的点,注意输出时,要按照顺序。
知道了定义,题目就很简单了,先做一次tarjan,然后找出度为0的连通分量;
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 10414 | Accepted: 4320 |
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 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
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
Source
Ulm Local 2003
要理解题意,求的是一种点,凡是这种点可以到达的点,都可以返回该点,也就是求出度为0的连通分量中所有的点,注意输出时,要按照顺序。
知道了定义,题目就很简单了,先做一次tarjan,然后找出度为0的连通分量;
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<map> #include<vector> using namespace std; const int maxn=5010; const int maxm=50010; struct Edge { int to,next; }edge[maxm]; int head[maxn],tot; void addedge(int u,int v) { edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } int Low[maxn],DFN[maxn],Stack[maxn],Belong[maxn]; int Index,top; int scc; bool Instack[maxn]; int num[maxn]; void Tarjan(int u) { int v; Low[u]=DFN[u]=++Index; Stack[top++]=u; Instack[u]=true; for(int i=head[u];i!=-1;i=edge[i].next) { v=edge[i].to; if(!DFN[v]) { Tarjan(v); if(Low[u]>Low[v]) Low[u]=Low[v]; } else if(Instack[v]&&Low[u]>DFN[v]) { Low[u]=DFN[v]; } } if(Low[u]==DFN[u]) { ++scc; do{ v=Stack[--top]; Instack[v]=false; Belong[v]=scc; num[scc]++; }while(v!=u); } } void solve(int N) { memset(DFN,0,sizeof(DFN)); memset(Instack,false,sizeof(Instack)); memset(num,0,sizeof(num)); Index=scc=top=0; for(int i=1;i<=N;++i) { if(!DFN[i]) Tarjan(i); } } void init() { tot=0; memset(head,-1,sizeof(head)); } int out[maxn]; int main() { int v,e; while(scanf("%d",&v)!=EOF&&v) { scanf("%d",&e); int a,b; init(); for(int i=0;i<e;++i) { scanf("%d %d",&a,&b); addedge(a,b); } solve(v); memset(out,0,sizeof(out)); for(int i=1;i<=v;++i) { for(int j=head[i];j!=-1;j=edge[j].next) { if(Belong[i]!=Belong[edge[j].to]) { out[Belong[i]]++; } } } for(int i=1;i<=v;++i) { if(!out[Belong[i]]) printf("%d ",i); } printf("\n"); } return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- [数论]poj2635__The Embarrassed Cryptographer
- [二分图匹配]poj2446__Chessboard
- [强连通分量]poj2186_Popular Cows
- POJ1050 最大子矩阵和