有向图的强连通分量之Kosaraju算法
Kosaraju_Algorithm:
step1:对原图G进行深度优先遍历,记录每个节点的离开时间。
step2:选择具有最晚离开时间的顶点,对反图GT进行遍历,删除能够遍历到的顶点,这些顶点构成一个强连通分量。
step3:如果还有顶点没有删除,继续step2,否则算法结束。
HDU1269
纠结快两天,开始一直MLE,以为是算法的问题,后来发现是数组开大了,改用链表.
提交后发现WA,网上一搜发现是一个Trap.
#include <algorithm> #include <functional> #include <list> #define MAX 10010 using namespace std; int n,m,a,b; bool vis[MAX]; list<int> rev[MAX],far[MAX],v,s; void first(int x) { vis[x]=false; for(list<int>::iterator i=rev[x].begin();i!=rev[x].end();i++) { if(vis[*i]) { first(*i); } } s.push_back(x); } void two(int x) { vis[x]=false; for(list<int>::iterator i=far[x].begin();i!=far[x].end();i++) { if(vis[*i]) { two(*i); } } } int main() { while(scanf("%d%d",&n,&m)!=EOF && (n+m))//(n=1 m=0) { for(int i=1;i<=n;i++) { rev[i].clear(); far[i].clear(); } memset(vis,true,sizeof(vis)); v.clear(); s.clear(); for(int i=0;i<m;i++) { scanf("%d%d",&a,&b); rev[a].push_back(b); far[b].push_back(a); if(vis[a]) { vis[a]=false; v.push_back(a); } if(vis[b]) { vis[b]=false; v.push_back(b); } } memset(vis,true,sizeof(vis)); while(v.size()) { if(vis[v.front()]) { first(v.front()); } v.pop_front(); } memset(vis,true,sizeof(vis)); int sum=0; sum=n==1?1:sum;//考虑n=1的情况 while(s.size()) { if(vis[s.back()]) { sum++; two(s.back()); } s.pop_back(); } printf("%s\n",sum==1?"Yes":"No"); } return 0; }