vijos P1022 Victoria的舞会2

vijos P1022 Victoria的舞会2

这道题目的意思就是求一个有向图有多少个强连通分量。求有向图强连通分量的方法:(1)做正向dfs,即如果用g[i][j]==1表示i结点到j结点有一条边,那么就是从i结点到j结点的遍历,在dfs函数的最后加上这么两行代码:count++;finish[count]=nownow表示当前所在dfs函数的结点。finish数组记录退出dfs函数的顺序。(2)按照finish数组中记录值的顺序做逆向dfs,即如果i结点到j结点有边,那么做从ji的遍历。

以下是我的代码,我把正向dfs和逆向dfs写在了一个函数里:

#include < stdio.h >
#define  MAXN 201
long  n,ans,count,g[MAXN][MAXN],finish[MAXN],visit[MAXN];
void  init()
{
    
long i,j,tmp;
    scanf(
"%ld",&n);
    
for(i=0;i<=n;i++)
      
for(j=0;j<=n;j++)
        g[i][j]
=0;
    
for(i=1;i<=n;i++)
    
{
       scanf(
"%ld",&tmp);
       
while(tmp!=0)
       
{
          g[i][tmp]
=1;
          scanf(
"%ld",&tmp);
       }

    }

}

void  dfs( long  now, long  bj)
{
    
long i;
    visit[now]
=1;
    
switch(bj)
    
{
       
case 1:
          
for(i=1;i<=n;i++)
          
if(g[now][i]==1&&!visit[i])
          
{
             visit[i]
=1;
             dfs(i,bj);
          

          count
++;
          finish[count]
=now;
          
break;
       
case 2:
          
for(i=1;i<=n;i++)
            
if(g[i][now]==1&&!visit[i])
            
{
               visit[i]
=1;
               dfs(i,bj);
            }

    }

}

void run()
{
    
long i;
    count
=0;
    ans
=0;
    
for(i=0;i<=n;i++)
      visit[i]
=0;
    
for(i=1;i<=n;i++)
      
if(!visit[i])
        dfs(i,
1);
    
for(i=0;i<=n;i++)
      visit[i]
=0;
    
for(i=n;i>=1;i--)
      
if(!visit[finish[i]])
      
{
         ans
++;
         dfs(finish[i],
2);
      }

    printf(
"%ld\n",ans);
}

int main()
{
    init();
    run();
return 0;
}

你可能感兴趣的:(vijos P1022 Victoria的舞会2)