Title Description
Each cow dreams of becoming a star in the bullpen. Like all cows are cows cow is a star. All milk
Cattle are narcissistic per cow always like to own. Between cows "like" can be delivered - if A hi
Huan B, B like C, then A also like C. A total of N cowshed cows given love relationship between the number of cows, you
Calculate how many cows can become a star.
Input Format
first line: space-separated by two integers: N and M
second row to row M + 1: an integer of two space-separated each line: A and B, and A represent like B
Output Format
The first line: a single integer representing the number of stars cows
Sample input and output
Input # 1 copy
3 3
1 2
2 1
2 3
Output # 1 copy
1
Description / Tips
Only 3 cows can be a star
【data range】
10% of the data N <= 20, M <= 50
30% of the data N <= 1000, M <= 20000
70% of the data N <= 5000, M <= 50000
100% data N <= 10000, M <= 50000
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
const int maxn = 1e5+3;
int head[maxn*20], dfn[maxn], low[maxn];//dfn是时间戳low是最小的时间戳head头
int chudu[maxn], rudu[maxn], id[maxn], all[maxn];//id是染色后的点 all是染色的点数
bool instal[maxn];int cnt, tot, gg;//instal是判断在不在栈中
stack<int>s;
struct Edge{
int next, to;
}edge[maxn*20];//链式前向星存图
inline void add(int x, int y) {
cnt++;
edge[cnt].to = y;
edge[cnt].next = head[x];
head[x] = cnt;
}
void init() {
while(!s.empty()) {
s.pop();
}
gg = 0;
memset(head, 0, sizeof(head));
memset(dfn, 0, sizeof(dfn));
memset(instal, false, sizeof(instal));
memset(all, 0, sizeof(all));
memset(chudu, 0, sizeof(chudu));
memset(id, 0, sizeof(id));
}
//链式前向星加边
void targin(int x) {
dfn[x] = low[x] = ++cnt;
s.push(x);
instal[x] = true;
for(int i = head[x];i;i = edge[i].next) {
int u = edge[i].to;
if(!dfn[u]) {
targin(u);
low[x] = min(low[x], low[u]);
}
else if(instal[u]) low[x] = min(low[x], dfn[u]);
}
int k;
if(low[x] == dfn[x]) {
++gg;
do{
k = s.top();s.pop();
instal[k] = false;
id[k] = gg;all[gg]++;//id是染色gg是第一次的点把所有的一个联通快的点缩成这个点all是存的缩点的点的数量
}while(x != k);
}
}//强连通
int main() {
int n , m;
while(~scanf("%d%d", &n, &m)) {
init();
int a, b;
for(register int i = 1;i <= m;++i) {
scanf("%d%d", &a, &b);
add(a, b);
}
for(register int j = 1;j <= n;++j) {
if(!dfn[j]) {
targin(j);
}
}
for(register int i = 1;i <= n;++i) {
for(int j = head[i];j;j = edge[j].next) {
int u = edge[j].to;
if(id[i] != id[u]) {
chudu[id[i]]++;
}
}
}
int tt = 0;
for(register int i = 1;i <= gg;++i) {
if(!chudu[i]) {
if(tt) {
puts("0");return 0;
}
tt = i;
}//如果入度为0且点数有两个就没有明星牛因为两个以上的点不能连接所以没有如果低于两个就求出入度为1的点的缩点数既是这个联通快数就是明星牛的所有
}
printf("%d\n", all[tt]);
}
return 0;
}