0
点赞
收藏
分享

微信扫一扫

poj 2186 Popular Cows(强连通分量)


题目:​​http://poj.org/problem?id=2186​​


Popular Cows


Time Limit: 2000MS

 

Memory Limit: 65536K

Total Submissions: 27673

 

Accepted: 11139


Description


Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is
popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.


Input


* Line 1: Two space-separated integers, N and M

* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.


Output


* Line 1: A single integer that is the number of cows who are considered popular by every other cow.


Sample Input


3 3 1 2 2 1 2 3


Sample Output


1

分析:


题目大意:如果A牛崇拜B牛,B牛崇拜C牛,则A牛也崇拜C牛。寻找有多少头牛它被所有的其他的牛崇拜。


关于强连通图:如果有向图G的任何两顶点都互相可达,则称图G是强连通图,如果有向图G存在两顶点u和v,使得u不能到达v或者v不能到达u,则称图G是非强连通图。


在有向无环图中有这样的点很特殊:outdegree=0 和 indegree=0的点。尝试将强连通分量压缩,通过缩点把杂乱的有向图变成一幅有向无环图,出度为0的点个数设为k,如果k=1那么就表明整个图是连通的,结果就是压缩点的个数,k>1则表明图不是连通的,结果是0。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int M=5e4+10,N=1e4+10;
int head[N],ed;
struct node{
int to,next;
}edge[M];
int sta[N],vis[N],low[N],dfn[N],out[N],top;
void init(){
ed=0;
memset(head,-1,sizeof(head));
memset(edge,0,sizeof(edge));
memset(out,0,sizeof(out));
memset(sta,0,sizeof(sta));
}
void addedge(int a,int b){
edge[ed].to=b;
edge[ed].next=head[a];
head[a]=ed++;
}
void tarbfs(int k,int cnt,int &num){
vis[k]=1;
low[k]=cnt;
dfn[k]=cnt;
sta[top++]=k;
for(int i=head[k];i>-1;i=edge[i].next){
if(vis[edge[i].to]==0) tarbfs(edge[i].to,++cnt,num);
if(vis[edge[i].to]==1) low[k]=min(low[k],low[edge[i].to]);
}
if(dfn[k]==low[k]){
++num;
while(top>0&&sta[top]!=k){
top--;
low[sta[top]]=num;
vis[sta[top]]=2;
}
}
}
int tarjan(int n){
int num=0,cnt=1;
top=0;
memset(vis,0,sizeof(vis));
memset(low,0,sizeof(low));
for(int i=1;i<=n;i++){
if(vis[i]==0) tarbfs(i,cnt,num);
}
return num;
}

int main()
{
//freopen("cin.txt","r",stdin);
int n,m;
while(cin>>n>>m){
int a,b;
init();
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
addedge(a,b);
}
int num=tarjan(n);
for(int i=1;i<=n;i++){
for(int j=head[i];j>-1;j=edge[j].next){
if(low[i]!=low[edge[j].to]) out[low[i]]++;
}
}
int sum=0,x;
for(int i=1;i<=num;i++){
if(out[i]==0){ sum++; x=i; }
}
if(sum==1){
sum=0;
for(int i=1;i<=n;i++){
if(low[i]==x) sum++;
}
printf("%d\n",sum);
}
else puts("0");
}
return 0;
}



举报

相关推荐

0 条评论