poj2553The Bottom of a Graph(强连通+缩点)
来源:互联网 发布:苏豪控股网络 编辑:程序博客网 时间:2024/05/29 11:20
The Bottom of a Graph
Time Limit: 3000MS Memory Limit: 65536KTotal Submissions: 7699 Accepted: 3161
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.
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 31 3 2 3 3 12 11 20
Sample Output
1 32
Source
Ulm Local 2003
题目大意:给定一个有向图,求一个点集,要求这个点集里的所有点能到达的点,也都能到达这个点。
题目分析:就是求强连通嘛,不过并不是求所有的强连通。因为强连通之间也可能有边相连。将强连通缩点后就将一张有向图转化成DAG,只能将其中出度为0的强连通分量输出,因为只有这些强连通分量中的点能够相互到达。其他的强连通分量可以到达这个强连通分量,但是回不去了,所以不符合。
详情请见代码:
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N = 5005;const int M = 1000005;struct edge{ int to,next;}g[M];int head[N];int scc[N];int stack1[N];int stack2[N];int out[N];int vis[N];int ans[N];int n,m;void init(){ for(int i = 1;i <= n;i ++) { head[i] = -1; scc[i] = out[i] = vis[i] = 0; }}void dfs(int cur,int &sig,int &ret){ vis[cur] = ++ sig; stack1[++stack1[0]] = cur; stack2[++stack2[0]] = cur; for(int i = head[cur];i != -1;i = g[i].next) { if(vis[g[i].to] == 0) dfs(g[i].to,sig,ret); else if(scc[g[i].to] == 0) { while(vis[stack2[stack2[0]]] > vis[g[i].to]) stack2[0] --; } } if(stack2[stack2[0]] == cur) { ++ret; stack2[0] --; do { scc[stack1[stack1[0]]] = ret; }while(stack1[stack1[0] --] != cur); }}int Gabow(){ int i,sig,ret; stack1[0] = stack2[0] = sig = ret = 0; for(i = 1;i <= n;i ++) if(!vis[i]) dfs(i,sig,ret); return ret;}void solve(){ int i,j,num; num = Gabow(); if(num == 1) { for(i = 1;i < n;i ++) printf("%d ",i); printf("%d\n",i); return; } for(i = 1;i <= n;i ++) { for(j = head[i];j != -1;j = g[j].next) { if(scc[i] != scc[g[j].to]) out[scc[i]] ++; } } int ansnum = 0; for(i = 1;i <= num;i ++) { if(out[i] == 0) { for(j = 1;j <= n;j ++) if(scc[j] == i) ans[ansnum ++] = j; } } sort(ans,ans + ansnum); for(i = 0;i < ansnum - 1;i ++) printf("%d ",ans[i]); printf("%d\n",ans[i]);}int nextint(){ char c; int ret; while((c = getchar()) > '9' || c < '0') ; ret = c - '0'; while((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + c - '0'; return ret;}int main(){ int i,j,a,b; while(n = nextint(),n) { m = nextint(); init(); for(i = 1;i <= m;i ++) { a = nextint(); b = nextint(); g[i].to = b; g[i].next = head[a]; head[a] = i; } solve(); } return 0;}//996K110MS
- poj2553The Bottom of a Graph(强连通+缩点)
- HOJ1520&&POJ2553The Bottom of a Graph强连通分量缩点+判断度数
- poj2553The Bottom of a Graph【scc+缩点】
- 【连通图|强连通+缩点】POJ-2553 The Bottom of a Graph
- POJ 2553 The Bottom of a Graph 强连通分量+缩点 tarjan or kosaraju
- Poj 2553 The Bottom of a Graph【强连通Kosaraju+缩点染色】
- poj2553 The Bottom of a Graph--Kosaraju算法 & 缩点 & 强连通分量
- poj 2553 The Bottom of a Graph 【强连通图中出度为0点】
- poj2553The Bottom of a Graph【tarjan中SCC出度是1】
- poj 2553 The Bottom of a Graph(强连通分量)
- POJ2553 The Bottom of a Graph 强连通 tarjan
- The Bottom of a Graph 强连通分量加缩点
- [强连通]poj 2553 The Bottom of a Graph
- poj2553-The Bottom of a Graph(强连通分量)
- POJ 2553 The Bottom of a Graph 强连通分量
- POJ 2553 The Bottom of a Graph 强连通
- POJ 2553 The Bottom of a Graph(强连通分量)
- 【POJ】The Bottom of a Graph 强连通
- 颜色代码表
- 黑马程序员——Collection
- string与string.h以及cstring的关系区别
- Timus 1303. Minimal Coverage
- obtainMessage与sendMessage
- poj2553The Bottom of a Graph(强连通+缩点)
- POJ - 3624 《Charm Bracelet》 【0-1背包】
- win8下安卓SDK Manager一闪而过解决方案
- C# 网络编程之Tcp实现客户端和服务器聊天
- Java命名规范
- 网络流(模板)
- 最健康的作息时间表
- poj 3328 Cliff Climbing 题解
- 快速排序