poj 2553 The Bottom of a Graph(Tarjan~)

找出度为0的强连通分量,然后按顺序输出即可。里面有句话开始没理解,就是如果有w到v,那么一定有v到w。意思是。如果v是sink,那么他连接的点一定也连接他。

 

这题比起之前做的两道来说简单多了,用tarjan了,还是不熟练啊。

 

这题没有bottom为空的情况。

 

 

#include <stdio.h> #include <stdlib.h> #include <iostream> #include <string.h> #include <stack> #define MAX 5010 using namespace std; typedef struct edge{ int to; edge *next; }edge; edge *map[MAX],node[MAX*3]; int n,ind,cou,scc; int numed[MAX],low[MAX],ins[MAX]; int sccf[MAX]; stack<int> s; void init() { cou = scc = 0; ind = 1; memset(sccf,0,sizeof(sccf)); memset(map,'/0',sizeof(map)); memset(node,'/0',sizeof(node)); memset(ins,0,sizeof(ins)); memset(low,0,sizeof(low)); memset(numed,0,sizeof(numed)); } void Tarjan(int u) { int v; low[u] = numed[u] = ind++; s.push(u); ins[u] = 1; edge *head = map[u]; while( head != NULL ) { v = head->to; if( !numed[v] ) { Tarjan(v); if( low[v] < low[u] ) low[u] = low[v]; } else if( ins[v] == 1 && numed[v] < low[u] ) low[u] = numed[v]; head = head->next; } if( numed[u] == low[u] ) { scc++; do { v = s.top(); s.pop(); ins[v] = 0; sccf[v] = scc; }while( u != v ); } } void Outdegree() { int i,outd[MAX],to; edge *head; memset(outd,0,sizeof(outd)); for(i=1; i<=n; i++) { head = map[i]; while( head != NULL ) { to = head->to; if( sccf[i] != sccf[to] ) outd[sccf[i]]++; head = head->next; } } for(i=1; i<=n; i++) if( outd[sccf[i]] == 0 ) printf("%d ",i); printf("/n"); } int main() { int m,from,to,i; while( scanf("%d",&n) != EOF && n ) { init(); scanf("%d",&m); while( m-- ) { scanf("%d %d",&from,&to); node[cou].to = to; node[cou].next = map[from]; map[from] = &node[cou++]; } for(i=1; i<=n; i++) if( !numed[i] ) Tarjan(i); Outdegree(); } return 0; }  

你可能感兴趣的:(struct,null,Graph)