Description
每头牛都想成为牛群中的红人。给定n头牛和m个有序对(a,b),(a,b)表示牛a认为牛b是红人。该关系有传递性,所以如果牛a认为牛b是红人,牛b认为牛c是红人,那么牛a认为牛c也是红人。求被其他所有牛认为是红人的牛的总数
Input
第一行两个整数n和m表示牛数和关系数,之后m行每行两个整数a和b表示牛a认为牛b是红人
Output
输出被其他所有牛认为是红人的牛的个数
Sample Input
3 3
1 2
2 1
2 3
Sample Output
1
Solution
题意:有N头牛 每一头牛都梦想着成为popular cow,(但这是不可能滴) 有m组仰慕的关系,仰慕有传递性 比如说A觉得B是popular and B thinks C is popular, then A thinks C is popalur also;
现在问有多少头牛是会被其他牛都仰慕。
思路:求强连通分量,缩成点 点内的头当然是相互仰慕的咯!! 然后求新的图 的出度 出度也0的点就会被所有牛仰慕 算出出度为0的强连通分量里点的个数就OK了,注意 可能有多个出度为0的点,这时输出0(不满足要求) 刚学korasaju 算法,所以用它做
Code
//Kosaraju 算法
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int VM=10010;
const int EM=50010;
struct Edge{
int to,nxt;
}edge1[EM],edge2[EM];
int head1[VM],head2[VM],n,cnt;
int scc_id[VM],vis[VM],order[VM],k,scc;
int indeg[VM],outdeg[VM];
void addedge(int cu,int cv){
edge1[cnt].to=cv;
edge1[cnt].nxt=head1[cu];
head1[cu]=cnt;
edge2[cnt].to=cu;
edge2[cnt].nxt=head2[cv];
head2[cv]=cnt++;
}
void DFS(int u){
for(int i=head1[u];i!=-1;i=edge1[i].nxt){
int v=edge1[i].to;
if(!vis[v]){
vis[v]=1;
DFS(v);
}
}
order[++k]=u;
}
void reDFS(int u){
for(int i=head2[u];i!=-1;i=edge2[i].nxt){
int v=edge2[i].to;
if(!scc_id[v]){
scc_id[v]=scc;
reDFS(v);
}
}
}
void Korasaju(){
int i,u;
k=scc=0;
memset(vis,0,sizeof(vis));
memset(scc_id,0,sizeof(scc));
memset(order,0,sizeof(order));
for(u=1;u<=n;u++)
if(!vis[u]){
vis[u]=1;
DFS(u);
}
for(i=n;i>0;i--){
u=order[i];
if(!scc_id[u]){
scc_id[u]=++scc;
reDFS(u);
}
}
}
void Count_deg(){
memset(indeg,0,sizeof(indeg));
memset(outdeg,0,sizeof(outdeg));
for(int u=1;u<=n;u++)
for(int i=head1[u];i!=-1;i=edge1[i].nxt){
int v=edge1[i].to;
if(scc_id[u]!=scc_id[v]){
indeg[scc_id[v]]++;
outdeg[scc_id[u]]++;
}
}
}
int main(){
//freopen("input.txt","r",stdin);
int m;
while(~scanf("%d%d",&n,&m)){
memset(head1,-1,sizeof(head1));
memset(head2,-1,sizeof(head2));
cnt=0;
int u,v;
while(m--){
scanf("%d%d",&u,&v);
addedge(u,v);
}
Korasaju();
Count_deg();
int count=0,loc;
for(int i=1;i<=scc;i++)
if(outdeg[i]==0){
count++;
loc=i;
}
if(count>1)
printf("0\n");
else{
count=0;
for(u=1;u<=n;u++)
if(scc_id[u]==loc)
count++;
printf("%d\n",count);
}
}
return 0;
}