POJ 2553 taarjan缩点+度数

The Bottom of a Graph

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 8904   Accepted: 3689

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 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

题目意思:给一个n个结点,m条边的有向图,若一个点所能到达的其他点都能到达该点或一个点不能到达其他点,那么该点为sink,从小到达输出sink。

思路:这个题难在翻译上,特别是我这四级考了两次才过的人T-T,看懂了就很水了,先用tarjan缩点分块,然后求出没有出度的块的点标记下来,最后排序输出就行了。

代码:
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 #include <queue>
 7 #include <stack>
 8 using namespace std;
 9
10 #define N 5005
11 int n, m;
12 vector<int>ve[N];
13 int low[N], dfn[N], dfn_clock;
14 int in[N], out[N], instack[N], a[N], b[N];
15 int cnt;
16 stack<int>st;
17
18 void init(){
19     int i, j;
20     while(!st.empty()) st.pop();
21
22     for(i=0;i<=n;i++){
23         ve[i].clear();instack[i]=1;
24     }
25     memset(dfn,0,sizeof(dfn));
26     memset(in,0,sizeof(in));
27     memset(out,0,sizeof(out));
28 }
29
30 void tarjan(int u){
31     int i, j, v;
32     dfn[u]=low[u]=dfn_clock++;
33     st.push(u);
34     for(i=0;i<ve[u].size();i++){
35         v=ve[u][i];
36         if(!dfn[v]){
37             tarjan(v);
38             low[u]=min(low[u],low[v]);
39         }
40         else if(instack[v]){
41             low[u]=min(low[u],dfn[v]);
42         }
43     }
44     if(low[u]==dfn[u]){
45         cnt++;
46         while(1){
47             v=st.top();st.pop();
48             a[v]=cnt;instack[v]=0;
49             if(v==u) break;
50         }
51     }
52 }
53
54 main()
55 {
56     int i, j, k;
57     int x, y;
58     while(scanf("%d",&n)==1&&n){
59         scanf("%d",&m);
60         init();
61         while(m--){
62             scanf("%d %d",&x,&y);
63             ve[x].push_back(y);
64         }
65         dfn_clock=1;cnt=0;
66         for(i=1;i<=n;i++){
67             if(!dfn[i])
68             tarjan(i);
69         }
70         for(i=1;i<=n;i++){
71             for(j=0;j<ve[i].size();j++){
72                 x=ve[i][j];
73                 if(a[x]!=a[i]){
74                     out[a[i]]++;in[a[x]]++;
75                 }
76             }
77         }
78         k=0;
79         for(i=1;i<=n;i++){
80             if(!out[a[i]]){
81                 b[k++]=i;
82             }
83         }
84         sort(b,b+k);
85         printf("%d",b[0]);
86         for(i=1;i<k;i++) printf(" %d",b[i]);
87         cout<<endl;
88     }
89 }
时间: 2024-10-30 11:33:04

POJ 2553 taarjan缩点+度数的相关文章

poj 2553强连通+缩点

/*先吐槽下,刚开始没看懂题,以为只能是一个连通图0T0 题意:给你一个有向图,求G图中从v可达的所有点w,也都可以达到v,这样的v称为sink.求这样的v. 解;求强连通+缩点.求所有出度为0的点即为要求的点. 注意:可能有多个联通分支. */ #include<stdio.h> #include<string.h> #include<stdlib.h> #define N 5100 struct node { int u,v,w,next; }bian[N*N*2]

POJ 1236 tarjan缩点+度数

Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11441   Accepted: 4554 Description A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a li

poj 2553 The Bottom of a Graph 【强连通图中出度为0点】

题目:poj 2553 The Bottom of a Graph 题意:大概题意是给出一个有向图,求强连通缩点以后出度为0的点. 分析:入门题目,先强连通缩点,然后表示出度为0的,枚举输出即可. #include <cstdio> #include <vector> #include <iostream> #include <stack> #include <cstring> using namespace std; const int N =

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

POJ 2553 The Bottom of a Graph 题目链接 题意:给定一个有向图,求出度为0的强连通分量 思路:缩点搞就可以 代码: #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <stack> using namespace std; const int N = 5005; int n, m; vector&l

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

题目地址:POJ 2553 题目意思不好理解.题意是:G图中从v可达的全部点w,也都能够达到v,这种v称为sink.然后升序输出全部的sink. 对于一个强连通分量来说,全部的点都符合这一条件,可是假设这个分量还连接其它分量的话,则肯定都不是sink.所以仅仅须要找出度为0的强连通分量就可以. 代码例如以下: #include <iostream> #include <string.h> #include <math.h> #include <queue>

POJ 2553 The Bottom of a Graph(Tarjan,强连通分量)

解题思路: 本题要求 求出所有满足"自己可达的顶点都能到达自己"的顶点个数,并从小到大输出. 利用Tarjan算法求出强连通分量,统计每个强连通分量的出度,出度为0的强连通分量内的顶点即为所求顶点. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath

POJ 2553 The Bottom of a Graph TarJan算法题解

本题分两步: 1 使用Tarjan算法求所有最大子强连通图,并且标志出来 2 然后遍历这些节点看是否有出射的边,没有的顶点所在的子强连通图的所有点,都是解集. Tarjan算法就是模板算法了. 这里使用一个数组和一个标识号,就可以记录这个顶点是属于哪个子强连通图的了. 然后使用DFS递归搜索所有点及其边,如果有边的另一个顶点不属于本子强连通图,那么就说明有出射的边. 有难度的题目: #include <stdio.h> #include <stdlib.h> #include &l

POJ 2762 tarjan缩点+并查集+度数

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15494   Accepted: 4100 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

POJ - 2553 tarjan算法+缩点

题意: 给你n个点,和m条单向边,问你有多少点满足(G)={v∈V|∀w∈V:(v→w)⇒(w→v)}关系,并把这些点输出(要注意的是这个关系中是蕴含关系而不是且(&&)关系) 题解: 单独一个强连通分量中的所有点是满足题目要求的但如果它连出去到了其他点那里,要么成为新的强连通分量,要么失去原有的符合题目要求的性质所以只需tarjan缩点求出所有强连通分量,再O(E)枚举所有边,是否会成为连接一个分量与另一个分量的边——即一条出度——即可如果一个分量没有出度,那么他中间的所有点都是符合题目