在zyh的高中,学生会每一年都会评选受欢迎学生,所谓受欢迎的学生,就是被所有学生喜欢的学生。 每个学生都喜欢自己,碰巧的是,如果学生A 喜欢学生B ,学生B喜欢学生C, 那么学生A也喜欢学生C。 但是学生A喜欢学生B 并不意味着学生B喜欢学生A。 zyh参与了评选工作,苦逼的他被安排去购买奖品,于是他拿到了一张表,这张表有m条记录,每条记录由两个数字a,b组成,表示a,喜欢b ,但是由于学生太多了,他无法知道会有多少个受欢迎的学生,从而无法去购买奖品,你能帮他解决吗?
Input
第1行:两个以空格分隔的整数,N和M. 第2行到第N+M行:两个以空格分隔的数字A和B,意味着A喜欢B。 1<=N<10,000 , 1 <= M <= 50,000.
Output
输出一个数-zyh所需购买的奖品数。
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define ll long long
#define inf 0x3f3f3f3f
#define N 10010
using namespace std;
int V;
vector<int>G[N];
vector<int>rG[N];
vector<int>vs;
bool used[N];
int cmp[N];
void add_edge(int from,int to){
G[from].push_back(to);
rG[to].push_back(from);
}
void dfs(int v){
used[v]=true;
for(int i=0;i<G[v].size();i++){
if(!used[G[v][i]])dfs(G[v][i]);
}
vs.push_back(v);
}
void rdfs(int v,int k){
used[v]=true;
cmp[v]=k;
for(int i=0;i<rG[v].size();i++){
if(!used[rG[v][i]])rdfs(rG[v][i],k);
}
}
int scc(){
memset(used,0,sizeof(used));
vs.clear();
for(int v=0;v<V;v++){
if(!used[v])dfs(v);
}
memset(used,0,sizeof(used));
int k=0;
for(int i=vs.size()-1;i>=0;i--){
if(!used[vs[i]])rdfs(vs[i],k++);
}
return k;
}
int main(){
int m,a,b;
while(scanf("%d %d",&V,&m)!=EOF){
for(int i=0;i<V;i++){
G[i].clear();
rG[i].clear();
}
for(int i=0;i<m;i++){
scanf("%d %d",&a,&b);
a--;b--;
add_edge(a,b);
}
int n=scc();
int u=0,num=0;
for(int v=0;v<V;v++){
if(cmp[v]==n-1){
u=v;
num++;
}
}
memset(used,0,sizeof(used));
rdfs(u,0);
for(int v=0;v<V;v++){
if(!used[v]){
num=0;
break;
}
}
printf("%d\n",num);
}
return 0;
}