POJ 2553 强联通缩点,找出度为0的点。
The Bottom of a Graph
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 8019 | Accepted: 3313 |
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.
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.
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.![]()
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
题意:不解释。
思路:tarjin缩点,判断每个点所处连通分量出度是否为0,输出即可。
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
const int maxn=5010;
int head[maxn],tol,low[maxn],dfn[maxn],Stack[maxn],instack[maxn],belong[maxn],out[maxn],indexx,scc,top;
struct node
{
int to,next;
}edge[10*maxn];
void add(int u,int v)
{
edge[tol].to=v;
edge[tol].next=head[u];
head[u]=tol++;
}
void tarjin(int u)
{
low[u]=dfn[u]=++indexx;
Stack[top++]=u;instack[u]=1;
int i,v;
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(!dfn[v])
{
tarjin(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]=0;
belong[v]=scc;
}while(u!=v);
}
}
void solve(int n)
{
memset(instack,0,sizeof(instack));
memset(dfn,0,sizeof(dfn));
memset(belong,0,sizeof(belong));
scc=top=indexx=0;
int i,u,v;
for(i=1;i<=n;i++)if(!dfn[i])tarjin(i);
//cout<<scc<<endl;
//for(i=1;i<=n;i++)cout<<belong[i]<<" ";cout<<endl;
memset(out,0,sizeof(out));
for(u=1;u<=n;u++)
{
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(belong[u]!=belong[v])out[belong[u]]++;
// printf("u=%d,v=%d, %d %d\n",u,v,belong[u],belong[v]);
}
}
vector<int> s;
s.clear();
for(i=1;i<=n;i++)
{
// cout<<out[belong[i]]<<" ";
if(out[belong[i]]==0)s.push_back(i);
}
// cout<<endl;
int len=s.size();
if(len==0){puts("");return;}
for(i=0;i<len;i++)
{
printf("%d",s[i]);
if(i==len-1)puts("");
else cout<<" ";
}
}
int main()
{
int i,j,k,m,n;
while(~scanf("%d",&n)&&n)
{
scanf("%d",&m);
memset(head,-1,sizeof(head));tol=0;
while(m--)
{
scanf("%d%d",&i,&j);
add(i,j);
}
solve(n);
}
return 0;
}

浙公网安备 33010602011771号