有向图的强连通分量之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;
}
posted @ 2012-07-09 14:56  Eslizn  阅读(625)  评论(0编辑  收藏  举报