poj2553——The Bottom of a Graph(强连通分量)
2016-05-08 08:52
423 查看
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
3 3
1 3 2 3 3 1
2 1
1 2
0
Sample Output
1 3
2
昨天错了一晚上,今天换个模板就过了。。。
题意是求所有的sink node,即互相有连接的点。图中第一个样例里,1、3互相连接,但2、3没有,所以答案是1和3,。所以根据定义就知道是要求强连通分量里出度为0的点,然后把这些点按顺序输出
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
昨天错了一晚上,今天换个模板就过了。。。
题意是求所有的sink node,即互相有连接的点。图中第一个样例里,1、3互相连接,但2、3没有,所以答案是1和3,。所以根据定义就知道是要求强连通分量里出度为0的点,然后把这些点按顺序输出
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #define MAXN 5005 using namespace std; struct Node { int x,y,next; } edge[MAXN*MAXN]; int dfn[MAXN],low[MAXN],vis[MAXN],s[MAXN],belong[MAXN],head[MAXN]; int in[MAXN],out[MAXN]; //入度,出度 int n,tot=0,ssum=0,ans=0,times=0,t=0,ans2; void init() { memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(vis,0,sizeof(vis)); memset(low,0,sizeof(low)); memset(belong,0,sizeof(belong)); memset(out,0,sizeof(out)); tot=ssum=0; } void add(int x,int y) { edge[++tot].x=x; edge[tot].y=y; edge[tot].next=head[x]; head[x]=tot; } void tarjan(int x) { int y,i; times++; t++; dfn[x]=low[x]=times; vis[x]=1; s[t]=x; for (i=head[x]; i; i=edge[i].next) { y=edge[i].y; if (vis[y]==0) { tarjan(y); low[x]=min(low[x],low[y]); } if (vis[y]==1) low[x]=min(low[x],dfn[y]); } if (dfn[x]==low[x]) { ssum++; do { y=s[t--]; belong[y]=ssum; vis[y]=2; } while (y!=x); } } int main() { int i,j; while(cin >> n&&n) { init(); int v,u; scanf("%d",&j); while(j--) { scanf("%d%d",&u,&v); add(u,v); } for (i=1; i<=n; i++) if (vis[i]==0) tarjan(i); for (i=1; i<=tot; i++) if (belong[edge[i].x]!=belong[edge[i].y]) { out[belong[edge[i].x]]++; } for(i=1;i<=n;++i) if(out[belong[i]]==0) cout<<i<<" "; cout<<endl; } }
相关文章推荐
- 网络HTTP、TCP、UDP、Socket 知识总结
- 面向项目(六)—— 错误(异常)信息的书写
- 文本选择问题: css & js
- 他山之石02---opencv测量运行时间的函数
- Java学习·junit(单元测试框架)
- strong weak copy assign 的用法与区别
- Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) D. Bear and Two Paths 构造
- 推荐系统构建中的PCA和SVD算法
- Spine之九——反向动力学Inverse Kinematics (IK)
- Java学习路线图
- 祭立夏
- HDU1559 最大子矩阵
- bitmap分析
- zabbix3.0 监控mysql服务免用户名密码登录的问题故障处理详细过程
- 每天一个Linux命令(10)cp命令
- js简易猜数字
- 《java入门第一季》之面向对象(形式参数和返回值问题的深入研究3)
- 《java入门第一季》之面向对象(形式参数和返回值问题的深入研究3)
- 持续交付之三——持续集成
- Spine之八——网格和自由变形(FFD)