Popular Cows--POJ 2186

1、题目类型:图论、强连通分量、Tarjan算法。

2、解题思路:(1)建立图的邻接表;(2)Trajan算法求解并记录强连通分量;(3)判断强连通分量的入度,当存在多个出度为0时,输出0;当只存在唯一出度为0的强连通分量,则输出其内部节点的个数。

3、注意事项:图用邻接表表示,矩阵表示MLE;注意M=0的情况。

4、实现方法:

#include<iostream>
#include
<stack>
using namespace std;

struct TNode
{
int data;
TNode
*next;
};

int n,m,index,cnt,bcnt;
int dfn[10010],low[10010];
int a[50010],b[50010],flag[10010];
TNode
*map[10010],data[500100];
bool vis[10010];
stack
<int> S;

void Tarjan(int v)
{
TNode
*tmp;
dfn[v]
=low[v]=++cnt;
vis[v]
=true;
S.push(v);
for(tmp=map[v];tmp!=NULL;tmp=tmp->next)
{
int i=tmp->data;
if(!dfn[i])
{
Tarjan(i);
if(low[v]>low[i])
low[v]
=low[i];
}
else if(vis[i]&&low[v]>dfn[i])
{
low[v]
=dfn[i];
}
}
if(low[v]==dfn[v])
{
bcnt
++;
int j;
do
{
j
=S.top();
S.pop();
//用于标示点j在第bcnt个强连通分量里面
flag[j]=bcnt;
}
while(j!=v);
}
}

int main()
{
int i,ans,pos;
TNode
*P,*pre;
cin
>>n>>m;
if(m==0)
{
cout
<<0<<endl;
return 0;
}
//建立邻接表
for(i=1;i<=m;i++)
{
cin
>>a[i]>>b[i];
P
=&data[index++];
P
->data=b[i];
if(map[a[i]]==NULL)
{
map[a[i]]
=P;
}
else
{
pre
=map[a[i]]->next;
P
->next=pre;
map[a[i]]
->next=P;
}
}
for(i=1;i<=n;i++)
{
if(!dfn[i])
Tarjan(i);
}

memset(vis,
0,sizeof(vis));
for(i=1;i<=m;i++)
{
if(flag[a[i]]!=flag[b[i]])
vis[flag[a[i]]]
=1;
}
cnt
=0;
for(i=1;i<=bcnt;i++)
{
if(!vis[i])
{
cnt
++;
pos
=i;
}
}
if(cnt>1)
{
cout
<<0<<endl;
}
else
{
ans
=0;
for(i=1;i<=n;i++)
if(flag[i]==pos)
ans
++;
cout
<<ans<<endl;
}
return 0;
}

 

 

 

posted @ 2010-08-09 20:39  勇泽  阅读(823)  评论(0编辑  收藏  举报