Description
每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。
Input
第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可
能出现多个A,B)
Output
一个数,即有多少头牛被所有的牛认为是受欢迎的。
Sample Input
3 3
1 2
2 1
2 3
1 2
2 1
2 3
Sample Output
1
HINT
100%的数据N<=10000,M<=50000
题解
好久没打$tarjan$了,码在这当模板存着。
//It is made by Awson on 2017.9.24
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
using namespace std;
const int N = ;
const int M = ;
int Read() {
char ch = getchar();
int sum = ;
while (ch < '' || ch > '') ch = getchar();
while (ch >= '' && ch <= '') sum = (sum<<)+(sum<<)+ch-, ch = getchar();
return sum;
} int n, m, u, v;
struct tt {
int from, to, next;
}edge[M+];
int path[N+], top;
int dfn[N+], low[N+], t;
bool vis[N+];
int S[N+], topS;
int sccno[N+], sccnum;
int in[N+], tot[N+]; void add(int u, int v) {
edge[++top].to = v;
edge[top].from = u;
edge[top].next = path[u];
path[u] = top;
}
void tarjan(int r) {
dfn[r] = low[r] = ++t;
vis[r] = ;
S[topS++] = r;
for (int i = path[r]; i; i = edge[i].next) {
if (!dfn[edge[i].to]) {
tarjan(edge[i].to);
low[r] = Min(low[edge[i].to], low[r]);
}
else if (vis[edge[i].to])
low[r] = Min(low[r], dfn[edge[i].to]);
}
if (dfn[r] == low[r]) {
sccnum++;
while (topS > && S[topS] != r) {
vis[S[--topS]] = ;
sccno[S[topS]] = sccnum;
tot[sccnum]++;
}
}
}
void work() {
n = Read(), m = Read();
for (int i = ; i <= m; i++) {
u = Read(), v = Read();
add(u, v);
}
for(int i = ; i <= n; i++)
if(!dfn[i]) tarjan(i);
for (int i = ; i <= m; i++)
if (sccno[edge[i].to] != sccno[edge[i].from])
in[sccno[edge[i].from]]++;
int ans = , cntt = ;
for (int i = ; i <= sccnum; i++)
if (!in[i]) cntt++, ans=i;
if (cntt == ) printf("%d\n", tot[ans]);
else printf("0\n");
}
int main() {
work();
return ;
}