心如止水
Je n'ai pas le temps
posts - 400,comments - 130,trackbacks - 0

这道题目的意思就是求一个有向图有多少个强连通分量。求有向图强连通分量的方法:(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;
}

posted on 2010-01-06 20:02 lee1r 阅读(340) 评论(2)  编辑 收藏 引用 所属分类: 题目分类:图论

FeedBack:
# re: vijos P1022 Victoria的舞会2
2010-02-25 22:19 | onion.
这和舞会有什么关系= = 啊...   回复  更多评论
  
# re: vijos P1022 Victoria的舞会2
2010-02-26 19:34 | Lee1R
@onion.
没有办法……题目名称就是这个。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理