tarjan算法和Kosaraju算法是求有向图的强连通分量的算法;
#include<iostream> #include<cstring> using namespace std; int map[100][100],nmap[100][100]; int visit[100]; int time1[100]; int post[100]; int n,m,num=0,postid=0; void dfs(int id); void ndfs(int id); int main() { cin>>n>>m; for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; map[x][y]=1; nmap[y][x]=1; } for(int i=1;i<=n;i++) if(visit[i]==0) dfs(i); for(int i=n;i>=1;i--) if(visit[post[i]]==1) { ndfs(post[i]); num++; } cout<<num<<endl; return 0; } void dfs(int id) { visit[id]=1; for(int i=1;i<=n;i++) if(visit[i]==0 && map[id][i]) dfs(i); postid++; post[postid]=id; } void ndfs(int id) { visit[id]=0; for(int i=1;i<=n;i++) if(visit[i]==1 && nmap[id][i]) ndfs(i); }
#include<cstdio> #include<algorithm> #include<string.h> using namespace std; struct node { int v,next; }edge[1001]; int DFN[1001],LOW[1001]; int stack[1001],heads[1001],visit[1001],cnt,tot,index; void add(int x,int y) { edge[++cnt].next=heads[x]; edge[cnt].v = y; heads[x]=cnt; return ; } void tarjan(int x) { DFN[x]=LOW[x]=++tot; stack[++index]=x; visit[x]=1; for(int i=heads[x]; i!=-1; i=edge[i].next) { if(!DFN[edge[i].v]) { tarjan(edge[i].v); LOW[x]=min(LOW[x],LOW[edge[i].v]); } else if(visit[edge[i].v ]) { LOW[x]=min(LOW[x],DFN[edge[i].v]); } } if(LOW[x]==DFN[x]) { do { printf("%d ",stack[index]); visit[stack[index]]=0; index--; } while(x!=stack[index+1]); printf("\n"); } return ; } int main() { memset(heads,-1,sizeof(heads)); int n,m; scanf("%d%d",&n,&m); int x,y; for(int i=1; i<=m; i++) { scanf("%d%d",&x,&y); add(x,y); } for(int i=1; i<=n; i++) if(!DFN[i]) tarjan(i); return 0; }