求有向图中强连通分量的个数

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int MAX_N=10005;
vector<int> G[MAX_N]; 
vector<int> rG[MAX_N];//存储边反向之后的图 
vector<int> PostOrder;//存储图的后序遍历 
int V,E;
bool used[MAX_N];
int comp[MAX_N];//存储每个结点所属的联通分量 
void addEdge(int u,int v)
{
    G[u].push_back(v);
    rG[v].push_back(u);
}
void dfs(int u)
{
    used[u]=true;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if(!used[v])
            dfs(v);
    }
    PostOrder.push_back(u);
}

void rdfs(int u,int k)
{
    used[u]=true;
    comp[u]=k;
    for(int i=0;i<rG[u].size();i++)
    {
        int v=rG[u][i];
        if(!used[v])
            rdfs(v,k);
    }
}

int scc()
{
    memset(used,false,sizeof(used));
    for(int i=1;i<=V;i++)
    {
        if(!used[i])
            dfs(i);
    }
    memset(used,false,sizeof(used));
    int k=0;
    for(int i=PostOrder.size()-1;i>=0;i--)
    {
        int v=PostOrder[i];
        if(!used[v])
            rdfs(v,k++);
    }
    return k;
}
int main()
{
    scanf("%d %d",&V,&E);
    for(int i=0;i<E;i++)
    {
        int u,v;
        scanf("%d %d",&u,&v);
        addEdge(u,v);
    }
    printf("%d\n",scc());
    return 0;
}

 

posted on 2015-09-22 10:51  vCoders  阅读(2244)  评论(0编辑  收藏  举报

导航