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

POJ 2186 Popular Cows

2016-10-09 20:03 190 查看
POJ 2186 Popular Cows

题意:有n头牛,m个关系,每个关系A,B表示A牛认为B牛很受欢迎。若A牛认为B牛很受欢迎,B牛认为C牛很受欢迎,则A牛也认为C牛很受欢迎。让你输出有几头牛被所有其他的牛认为很受欢迎。

思路:先找出所有的强连通分量,若出度为0的点只有一个,求这个点里包含的所有点的个数。若出度为0的点不止一个,则没有最受欢迎的牛,输出0。

题解:

#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
const int maxn=50000+10;
struct edge{
int from,to;
}es[maxn];
int first[maxn],next[maxn];
int tot=0;
void build(int ff,int tt)
{
es[++tot]=(edge){ff,tt};
next[tot]=first[ff];
first[ff]=tot;
}
stack<int>q;
int pre[maxn],scc_num[maxn],cnt,scc_cnt;
int dfs(int u)
{
int lowu=pre[u]=++cnt;
q.push(u);
for(int i=first[u];i;i=next[i])
{
int v=es[i].to;
if(!pre[v])
{
int lowv=dfs(v);
lowu=min(lowu,lowv);
}
else if(!scc_num[i])
{
lowu=min(lowu,pre[v]);
}
}
if(lowu==pre[u])
{
scc_cnt++;
while(1)
{
int v=q.top(); q.pop();
scc_num[v]=scc_cnt;
if(u==v)
{
break;
}
}
}
return lowu;
}
int a[maxn];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(first,0,sizeof(first));
memset(a,0,sizeof(a));
memset(next,0,sizeof(next));
memset(pre,0,sizeof(pre));
memset(es,0,sizeof(es));
tot=0,scc_cnt=0,cnt=0;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
build(x,y);
}
for(int i=1;i<=n;i++)
{
if(!pre[i])
{
dfs(i);
}
}
for(int i=1;i<=n;i++)
{
for(int j=first[i];j;j=next[j])
{
if(scc_num[i]!=scc_num[es[j].to])
{
a[scc_num[i]]++;
}
}
}
int ans=0,t;
for(int i=1;i<=scc_cnt;i++)
{
if(!a[i])
{
ans++;
t=i;
}
}
if(ans==1)
{
ans=0;
for(int i=1;i<=n;i++)
{
if(scc_num[i]==t)
{
ans++;
}
}
printf("%d\n",ans);
}
else
{
printf("0\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: