It's a tragedy to read the wrong question. I thought that, like Popular Cow, all vertices can be reached as sink points. Actually, it means that all vertices with paths from w to v and from v to w are called sink points, therefore, w-> v has edges while v-> w has no edges. Such a vertex is not a sink vertex. The sink point is used only when both of the preceding conditions are met.
Analysis of this question:
The first judgment is e (a-> B), e (B-> c) => e (a-> c), that is, the edge has a transfer relationship, in this way, the reachable relationship can be passed. Of course, you can pass the accessibility through bellman. However, the implementation efficiency is obviously very low. Therefore, we can reduce the graph to many strongly connected components, and represent the relationship between each vertex through the relationship between strongly connected components, in this way, you don't have to bother transferring the edge relationship. You can give the information of each vertex to your own shrinkage point. If S1-> S2, that is, all vertices in S1 have edges, while S2-> S1 has no edges (otherwise S1, S2 belongs to a strongly connected node ), obviously, all vertices in S1 do not meet the sink condition. This problem is converted to finding all vertices in the strongly connected component without degree, and output by size.
The key to this question is that you don't need to really scale down the points, but store the labels of the strongly connected components of all points in a P array. Through the relationship between each edge of each vertex, if the vertex has an outbound edge and the outbound edge connects the strong connection to other strong connections, then the strong connection has an outbound degree, mark the strong connection, traverse the vertex, and output the corresponding vertex in the strong connection without degree.
//#include<iostream>#include<stdio.h>#include<stack>#define MAXN 5005using namespace std;struct Node{ int v; Node *next;}Edge[MAXN*MAXN],*ptr[MAXN];int V,E;int DFN[MAXN],LOW[MAXN],SCC[MAXN],P[MAXN];bool visited[MAXN],inS[MAXN];int SCCNum;stack<int>myStack;int min( int a,int b ){ return a<b?a:b; }void addEdge( int u,int v,int num ){ Node *p=&Edge[num]; p->v=v; p->next=ptr[u]; ptr[u]=p;}int cnt;void Tarjan(int pre){ LOW[pre]=DFN[pre]=++cnt; Node *p=ptr[pre]; myStack.push(pre); visited[pre]=true; inS[pre]=true; int u=pre; while( p ) { if( !visited[p->v] ) { Tarjan(p->v); LOW[u]=min( LOW[u],LOW[p->v] ); } else if( inS[p->v] ) LOW[u]=min( LOW[u],DFN[p->v] ); p=p->next; } if( DFN[u]==LOW[u] ) { int v; SCCNum++; do { v=myStack.top(); myStack.pop(); inS[v]=false; SCC[SCCNum]++; P[v]=SCCNum; }while( u!=v ); }}bool FINISH;bool DFS( int pre ){ visited[pre]=true; int sum=0,i; for( i=1;i<=SCCNum;i++ ) sum+=visited[i]; if( sum==SCCNum ) return FINISH=true; Node *p=ptr[pre]; while( p ) { if( !visited[p->v] ) DFS(p->v); if( FINISH ) return true; p=p->next; } return false;}int main(){ while( scanf( "%d",&V )!=EOF ) { if( !V ) break ; scanf( "%d",&E ); int i,j; int u,v; for( i=0;i<=V;i++ ) ptr[i]=NULL; cnt=0;SCCNum=0;FINISH=false; while( !myStack.empty() ) myStack.pop(); for( i=1;i<=E;i++ ) { scanf( "%d %d",&u,&v ); addEdge( u,v,i ); } memset( DFN,0,sizeof(DFN) ); memset( LOW,0,sizeof(LOW) ); memset( visited,0,sizeof(visited) ); memset( inS,0,sizeof(inS) ); for( i=1;i<=V;i++ ) if( DFN[i]==0 ) Tarjan(i); bool outD[MAXN]; memset( outD,0,sizeof(outD) ); for( int i=1;i<=V;i++ ) { Node *p=ptr[i]; while( p ) { if( P[i]!=P[p->v] ) outD[ P[i] ]=true; p=p->next; } } for( i=1;i<=V;i++ ) { if( outD[P[i]]==false ) { printf( "%d",i );break; } } for( i++;i<=V;i++ ) { if( outD[P[i]]==false ) printf( " %d",i ); } printf( "\n" ); } return 0;}