在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;
}