HDOJ 1926 迷宫城堡

         求有向图的强连通分量的题目,判断任意两点是否连通就是判断强连通分量是否为一。这道题是用两次DFS求连通分量,很简单的Kosaraju算法,正向图进行一次DFS反向图进行一次DFS。推荐博客

http://www.cnblogs.com/luweiseu/archive/2012/07/14/2591370.html

代码:

#include<iostream>
using namespace std;
#define maxn 10001
struct Edge
{
       int v,next;
} e[maxn*10],re[maxn*10];
bool visit[maxn];
int t[maxn],n,head[maxn],size,rhead[maxn];
void AddEdge(int a,int b)
{
     e[size].v=b;
     e[size].next=head[a];
     head[a]=size;
     re[size].v=a;//建立反向图。
     re[size].next=rhead[b];
     rhead[b]=size;
     size++;
}
void DFS1(int u,int&cnt)
{
     visit[u]=true;
     for(int i=head[u]; i!=-1; i=e[i].next){
          int v=e[i].v;
          if( !visit[v])
              DFS1(v,cnt);
     }
     t[++cnt]=u;
}
void DFS2(int u)
{
     visit[u]=true;
     for(int i=rhead[u]; i!=-1; i=re[i].next){
             int v=re[i].v;
             if( !visit[v])
                 DFS2(v);
     }
}
int main()
{
    int cnt,m,a,b,i;
    while( scanf("%d%d",&n,&m)){
           if( n==0&&m==0) break; 
           
           memset(head,-1,sizeof(head));
           memset(rhead,-1,sizeof(rhead));
           memset(e,0,sizeof(e));
           size=0;
           
           while( m--){
                  scanf("%d%d",&a,&b);
                  AddEdge(a,b);
           }
           
           memset(visit,false,sizeof(visit));
           memset(t,0,sizeof(t));
           for(cnt=0,i=1; i<=n; i++){ //正向DFS
                if( !visit[i])
                    DFS1(i,cnt);
           } 
                
           memset(visit,false,sizeof(visit));
           for(cnt=0,i=n; i>=1; i--){ //反向DFS
                if( !visit[t[i]]){
                    DFS2(t[i]);
                    cnt++;
                }
           }
          
           if( cnt==1)
               printf("Yes\n");
           else
               printf("No\n"); 
    }
    return 0;
}


你可能感兴趣的:(算法,struct)