POJ2553 The Bottom of a Graph

来源:互联网 发布:电脑数据流量统计 编辑:程序博客网 时间:2024/05/16 22:16

Time Limit: 3000MS

 

Memory Limit: 65536K

Total Submissions: 7461

 

Accepted: 3064

Description

We will use the following (standard) definitions from graph theory. LetV be a nonempty and finite set, its elements being called vertices (or nodes). LetE be a subset of theCartesian(笛卡尔)  productV×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 lengthn of edgesei
E such thatei=(vi,vi+1) for a sequence of vertices(v1,...,vn+1). Thenp is called a path from vertexv1 to vertexvn+1 inG and we say thatvn+1 is reachable fromv1, writing(v1→vn+1).
Here are some new definitions. A node v in a graph G=(V,E) is called asink, if for every nodew inG that is reachable fromv,v is also reachable fromw. Thebottom of a graph is the subset of all nodes that are sinks, i.e.,
bottom(G)={vV|wV:(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 graphG. Each test case starts with an integer numberv, denoting the number of vertices ofG=(V,E), where the vertices will be identified by the integer numbers in the setV={1,...,v}. You may assume that1<=v<=5000. That is followed by a non-negative integere and, thereafter,e pairs of vertex identifiersv1,w1,...,ve,wewith 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 outputthe bottom of the specified graph on a single line. To this end, print the numbers ofall nodes that are sinks in sorted order separated by a single space character. If thebottom 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

Source

Ulm Local 2003

这是个强联通分支问题,bottom中的顶点属于强联通分支,且该强联通分支中不存到其他分支的的出边(可以存在其他联通分支到此联通分支的入边)。

#include <iostream>#include <memory>#include <cassert>#define _DEBUG 1#define MAXN 5000//最大顶点数typedef struct _arcNode{int vNode;//节点序号struct _arcNode *next; //下一个邻接顶点}ArcNode;int n,e;ArcNode * AdjList[MAXN+1];//图的邻接表ArcNode * rAdjList[MAXN+1];//图的逆邻接表int order_by_depthfirst[MAXN+1];//以深度遍历节点的顺序排列的节点int order_by_depthfirst_count=0;int belong[MAXN+1];//顶点属于哪个componentbool component_has_outEdge[MAXN+1];//components 是否有出边void add_an_edge(int from,int to){//增加一条边,包括正向边和反向边//添加正向边ArcNode *pNode1=new ArcNode();pNode1->vNode=to;pNode1->next=AdjList[from];AdjList[from]=pNode1;//添加反向边ArcNode *pNode2=new ArcNode();pNode2->vNode=from;pNode2->next=rAdjList[to];rAdjList[to]=pNode2;}void Gfs_visit1(int u,bool hasVisited[]){hasVisited[u]=true;ArcNode *p=AdjList[u];//邻接顶点列表for(;p;p=p->next){int v=p->vNode;if(!hasVisited[v])Gfs_visit1(v,hasVisited);}order_by_depthfirst[order_by_depthfirst_count++]=u;//将u加入排序数组}void genVistedOrder(){bool hasVisited[MAXN+1];memset(hasVisited,false,sizeof(hasVisited));order_by_depthfirst_count=0;//重置为0for(int i=1;i<=n;++i){if(!hasVisited[i])Gfs_visit1(i,hasVisited);}}void Gfs_visit(int u,int component){//反向图深度遍历if(belong[u]==-1){//如果未访问过belong[u]=component;//将u分配给强联通分支componentArcNode *p=rAdjList[u];for(;p;p=p->next){int v=p->vNode;if(belong[v]!=-1){//设置强联通分支component分支有出度if(belong[v]!=component)//不属于本联通分支component_has_outEdge[belong[v]]=true;}elseGfs_visit(v,component);}}}int main(){#if _DEBUG==1freopen("2553.in","r",stdin);#endifint from,to;int i;while(scanf("%d",&n) && n!=0){//初始化memset(AdjList,0,sizeof(AdjList));memset(rAdjList,0,sizeof(rAdjList));memset(order_by_depthfirst,0,sizeof(order_by_depthfirst));memset(belong,-1,sizeof(belong));memset(component_has_outEdge,false,sizeof(component_has_outEdge));scanf("%d",&e);for(i=0;i<e;++i){scanf("%d %d",&from,&to);add_an_edge(from,to);}genVistedOrder();//生成访问顺序int component=0;//强联通分支for(i=n-1;i>=0;--i){//按照拓扑排序顺序,遍历反向图int u=order_by_depthfirst[i];if(belong[u]==-1){Gfs_visit(u,component++);}}bool flag=true;for(i=1;i<=n;++i){int belong_to_component=belong[i];if(!component_has_outEdge[belong_to_component]){//该分支没有出边if(flag){printf("%d",i);flag=false;}elseprintf(" %d",i);}}printf("\n");}return 0;}


一开始最后打印代码是这样的
char *s="";
  for(i=1;i<=n;++i){
   int belong_to_component=components[i];
   if(!component_has_outdegree[belong_to_component]){//该分支没有出度
    printf("%s%d",s,i);
    s=" ";
   }
  }
  printf("\n");

提交一直是RuntimeERR,可能char *s="";不认。改了之后才Accept

原创粉丝点击