您的位置:首页 > 运维架构

POJ 2186 Popular Cows (强连通分量)

2012-07-26 20:17 274 查看
题目大意:有n个牛,已知这些牛之间的崇拜关系,崇拜关系是可以传递的,例如:a崇拜b,b崇拜c,那么a崇拜c。问有多少牛被其他所有牛崇拜?

分析:根据崇拜关系建立有向图,已知同属于一个强连通分量的牛互相崇拜,通过求强连通缩点后,若出度为0的点只有一个,那么这一群牛就被其他所有牛崇拜,否则不存在被其他所有牛崇拜的牛。

View Code

#include <stdio.h>
#include <string.h>
#define N 10001
#define M 50001
int first
,next[M],v[M];
int rfirst
,rnext[M],rv[M];
int n,m,e;
int vis
,dfn
,id
,cnt,num
;
int dout
;
void init()
{
e=0;
memset(first,-1,sizeof(first));
memset(rfirst,-1,sizeof(rfirst));
}
void insert(int a,int b)
{
v[e]=b;
next[e]=first[a];
first[a]=e;

rv[e]=a;
rnext[e]=rfirst[b];
rfirst[b]=e++;
}
void dfs(int a)
{
int i,b;
vis[a]=1;
for(i=first[a];i!=-1;i=next[i])
{
b=v[i];
if(!vis[b]) dfs(b);
}
dfn[cnt++]=a;
}
void rdfs(int a)
{
int i,b;
vis[a]=1;
id[a]=cnt;
num[cnt]++;
for(i=rfirst[a];i!=-1;i=rnext[i])
{
b=rv[i];
if(!vis[b]) rdfs(b);
}
}
void solve()
{
int i,j,a,b,t;
cnt=0;
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
{
if(!vis[i]) dfs(i);
}
cnt=0;
memset(vis,0,sizeof(vis));
memset(num,0,sizeof(num));
for(t=n-1;t>=0;t--)
{
i=dfn[t];
if(!vis[i]) rdfs(i),cnt++;
}
memset(dout,0,sizeof(dout));
for(a=1;a<=n;a++)
{
for(i=first[a];i!=-1;i=next[i])
{
b=v[i];
if(id[a]^id[b]) dout[id[a]]++;
}
}
int x=0;
for(i=0;i<cnt;i++)
{
if(!dout[i])
{
x++;
j=i;
}
}
if(x>1) puts("0");
else    printf("%d\n",num[j]);
}
int main()
{
int a,b;
while(~scanf("%d%d",&n,&m))
{
init();
while(m--)
{
scanf("%d%d",&a,&b);
insert(a,b);
}
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: