hdu1269——迷宫城堡——————【kosaraju模板】

来源:互联网 发布:淘宝宝贝描述用什么做 编辑:程序博客网 时间:2024/06/08 08:07

这个算法可以解决判断和打印各个强连通分量的问题。对于本题,只要判断就行。

#include<stdio.h>#include<iostream>#include<vector>#include<algorithm>#include<string.h>using namespace std;const int MAXV=11000;vector<int>G[MAXV],T_G[MAXV];   //原图和转置图vector<int>S;                   //用来存放dfs后的各点离开时间int vis[MAXV],sccno[MAXV],scc_cnt;//vis标记,sccno记录各点属于哪个强连通分量,scc_cnt记录分量个数void dfs(int u){    if(vis[u])return ;    vis[u]=1;   //标记    for(int i=0; i<G[u].size(); i++)    {        dfs(G[u][i]);    }    S.push_back(u);}void T_dfs(int u){    if(sccno[u])return ;    sccno[u]=scc_cnt;       //u为该分量的一个点    for(int i=0; i<T_G[u].size(); i++)    {        T_dfs(T_G[u][i]);   //深搜该点    }}int find_scc(int n){    scc_cnt=0;    S.clear();    memset(vis,0,sizeof(vis));    memset(sccno,0,sizeof(sccno));    for(int i=1; i<=n; i++) //深搜1-n每个节点    {        dfs(i);    }    for(int i=n-1; i>=0; i--)   //搜索由晚到早离开的点    {        if(!sccno[S[i]])        {            scc_cnt++;          //分量个数增加            T_dfs(S[i]);                }    }    for(int i=1; i<=n; i++)    {        G[i].clear();        T_G[i].clear();    }    return scc_cnt;}void Transform(int n,vector<int>*Graph) //将图转置{    for(int i=1; i<=n; i++)    {        for(int j=0; j<Graph[i].size(); j++)        {            T_G[Graph[i][j]].push_back(i);        }    }}bool kosaraju(int n){    if(find_scc(n)==1)        return true;    return false;}int main(){    int n,m,a,b;    while(scanf("%d%d",&n,&m)!=EOF&&(n+m))    {        for(int i=0; i<m; i++)        {            scanf("%d%d",&a,&b);            G[a].push_back(b);        }        Transform(n,G);        if(kosaraju(n))            printf("Yes\n");        else            printf("No\n");   /*     for(int i=1;i<=scc_cnt;i++){                //scc_cnt表示强连通分量个数            for(int j=1;j<=n;j++){  //遍历所有点                if(sccno[j]==i)                     //如果该点在同一个强连通分量中输出                printf("%d ",j);            }            printf("\n");        }*/    }    return 0;}


0 0
原创粉丝点击