吐槽:学习算法的初期是很痛苦的,收割阶段确实很爽。图论,只要有正确的思路去解题的话,代码是很好写的。
题意:n个牛之间有相互崇拜的关系,并且崇拜关系是相互传递的,求有多少个牛被其他所有牛崇拜。崇拜关系可以是相互的。
解法:统计初度为零的两个集合,如果大于1,说明有两个以上的牛群之间是不会相互崇拜的。如果个数为1的话,说明这个牛群被其他牛群崇拜,并且在自己的集合里,崇拜关系是相互的。自然满足条件,统计个数即可。
/*
----------------------------------
Love is more than a word.
It says so much.
When I see these four letters,
I almost feel your touch.
This is only happened since
I fell in love with you.
Why this word does this,
I haven't got a clue.
To My Goddess
CY
----------------------------------
*/
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#define maxn 50000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define REP(i,a,b) for(i=a;i<=b;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define clehead(a) rep(i,maxn)a[i]=-1
/*
The time of story :
** while(1)
{
once upon a time,
there was a mountain,
on top of which there was a temple,
in which there was an old monk and a little monk.
Old monk was telling stories inside the temple.
What was he talking about?
** }
ÎûÎû
(*^__^*)
*/
#define sci(a) scanf("%d",&a)
#define scd(a) scanf("%lf",&a)
#define pri(a) printf("%d",a)
#define prie(a) printf("%d\n",a)
#define prd(a) printf("%lf",a)
#define prde(a) printf("%lf\n",a)
#define pre printf("\n")
#define LL(x) x<<1
#define RR(x) x<<|1
#define pb push_back
#define mod 90001
#define PI 3.141592657
const ull INF = 1LL << 61;
const int inf = int(1e5)+10;
const double eps=1e-5;
using namespace std;
struct node
{
int be;
int to,w;
int next;
}edge[50050];
bool cmp(int a,int b){
return a>b;
}
int head[maxn];
int m;
int low[maxn],dfn[maxn],stack[maxn],used[maxn];
int cnt=0;
int in[maxn],out[maxn];
void add(int x,int y)
{
edge[cnt].be=x;
edge[cnt].to=y;
edge[cnt++].next=head[x];
head[x]=(cnt-1);
}
void init()
{
memset(head,-1,sizeof(head));
cle(used),cle(low),cle(dfn),cle(in),cle(out);
m=0;
cnt=0;
}
int tarbfs(int k,int lay,int &scc_num)
{
used[k]=1;
low[k]=lay;
dfn[k]=lay;
stack[++m]=k;
for(int i=head[k];i!=-1;i=edge[i].next)
{
if(used[edge[i].to]==0)
{
tarbfs(edge[i].to,++lay,scc_num);
}
if(used[edge[i].to]==1)
{
low[k]=min(low[k],low[edge[i].to]);
}
}
if(dfn[k]==low[k])
{
++scc_num;
do{
low[stack[m]]=scc_num;
used[stack[m]]=2;
}while(stack[m--]!=k);
}
return 0;
}
int main()
{
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,k;
while(scanf("%d%d",&n,&k)!=EOF)
{
init();
int i,j;
int scc_num=0;
int lay=1;
for(i=1;i<=k;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
for(i=1;i<=n;i++)
{
if(used[i]==0)
{
tarbfs(i,lay,scc_num);
}
}
int ans=0;
int ip=0;
for(i=0;i<cnt;i++)
{
if(low[edge[i].be]!=low[edge[i].to])
{
out[low[edge[i].be]]++;
in[low[edge[i].to]]++;
}
}
for(i=1;i<=scc_num;i++)
{
if(out[i]==0)
{
ans++;
ip=i;
}
}
if(ans>1)
{
cout<<0<<endl;
}
else
{
ans=0;
for(i=1;i<=n;i++)
{
if(low[i]==ip)
{
ans++;
}
}
printf("%d\n",ans);
}
}
return 0;
}