POJ 2553 The Bottom of a Graph(强连通分量)
2016-02-04 22:24
806 查看
思路: 强连通分量题的老套路:求分量,缩点图,输出DAG的相关信息.
该题的答案就是那些DAG中出度为0的点 所代表的分量中包含的所有点.
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 that1<=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
该题的答案就是那些DAG中出度为0的点 所代表的分量中包含的所有点.
#include <cstdio> #include <queue> #include <cstring> #include <iostream> #include <cstdlib> #include <algorithm> #include <vector> #include <map> #include <string> #include <set> #include <ctime> #include <cmath> #include <cctype> #include <stack> using namespace std; #define maxn 10000+100 #define LL long long int cas=1,T; vector<int>G[maxn]; int pre[maxn]; int lowlink[maxn]; int sccno[maxn]; int num[maxn]; //在i编号scc中有多少个点 int dfs_clock,scc_cnt; int n,m; stack<int>S; void dfs(int u) { pre[u]=lowlink[u]=++dfs_clock; S.push(u); for (int i = 0;i<G[u].size();i++) { int v = G[u][i]; if (!pre[v]) { dfs(v); lowlink[u] = min(lowlink[u],lowlink[v]); } else if (!sccno[v]) { lowlink[u] = min (lowlink[u],pre[v]); } } if (lowlink[u] == pre[u]) { scc_cnt++; for (;;) { int x = S.top();S.pop(); sccno[x] = scc_cnt; num[scc_cnt]++; if (x==u) break; } } } void find_scc(int n) { dfs_clock=scc_cnt=0; memset(sccno,0,sizeof(sccno)); memset(pre,0,sizeof(pre)); for (int i = 1;i<=n;i++) if (!pre[i]) dfs(i); } int in[maxn]; int out[maxn]; int main() { //freopen("in","r",stdin); while (scanf("%d",&n)==1 && n) { scanf("%d",&m); for (int i = 0;i<=n;i++) G[i].clear(); memset(out,0,sizeof(out)); memset(num,0,sizeof(num)); for (int i = 1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); G[u].push_back(v); } find_scc(n); for (int i = 1;i<=scc_cnt;i++) { out[i]=true; } for (int u = 1;u<=n;u++) for (int i =0;i<G[u].size();i++) { int v = G[u][i]; if (sccno[u] != sccno[v]) out[sccno[u]]=false; } int b=0; int flag = 1; for (int i = 1;i<=n;i++) { if (out[sccno[i]]) { if (flag) printf("%d",i),flag=0; else printf(" %d",i); } } puts(""); } return 0; }
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 that1<=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
相关文章推荐
- Git服务器搭建全过程分步详解【转】
- HDU 2899 Strange fuction
- 图片上传
- 11个提问频率最高的PHP面试题
- hdoj 2516 取石子游戏
- could only be replicated to 0 nodes instead of minReplication (=1)
- JSF2.0学习笔记
- Android隐藏状态栏、导航栏
- Catch Bug
- 【poj1284-Primitive Roots】欧拉函数-奇素数的原根个数
- Linux Bash基本知识
- 通过java反射实现简单的关于MongoDB的对象关系映射(ORM).
- 使用HTML全局事件的一些功能,HTML元素,JS
- 1.8字符串- 翻转子串
- ios通过ipa快速提取里面的图片资源
- Joseph(hdu1443)
- uvalive 5873
- @property_@synthesize 配套使用
- qt LAN 通讯软件开发 进度 2016.2.4
- [转] ubuntu开启SSH服务