題意
n只牛,有愛慕關係,問幾隻奶牛被所有牛愛(自戀的)
題解
先Tarjan縮點,然後統計大點出度
調試記錄
統計的是大點出度
只能有一個出度爲0
#include <cstdio>
#include <stack>
#include <cstring>
#define maxn 50005
using namespace std;
struct node{
int to, next;
}e[maxn << 1];
int tot = 0, head[maxn];
void addedge(int u, int v){e[++tot] = (node){v, head[u]}; head[u] = tot;}
stack <int> s;
bool vis[maxn]; int color[maxn], val[maxn];
int Ctot = 0, dfn[maxn], low[maxn], Index = 0;
void Tarjan(int cur){
s.push(cur);
dfn[cur] = low[cur] = ++Index;
vis[cur] = true;
for (int i = head[cur]; i; i = e[i].next){
if (!dfn[e[i].to]){
Tarjan(e[i].to);
low[cur] = min(low[cur], low[e[i].to]);
}
else if (vis[e[i].to]) low[cur] = min(low[cur], low[e[i].to]);
}
if (dfn[cur] == low[cur]){
Ctot++; val[Ctot] = 0;
while (s.top() != cur){
val[Ctot]++;
color[s.top()] = Ctot;
vis[s.top()] = false;
s.pop();
}
val[Ctot]++;
color[s.top()] = Ctot;
vis[s.top()] = false;
s.pop();
}
}
struct Q{
int u, v;
}q[maxn];
int n, m;
int main(){
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++){
scanf("%d%d", &q[i].u, &q[i].v);
addedge(q[i].u, q[i].v);
}
for (int i = 1; i <= n; i++)
if (!dfn[i]) Tarjan(i);
memset(e, 0, sizeof e);
memset(head, 0, sizeof head);
tot = 0;
int OutDex[maxn];
for (int i = 1; i <= m; i++)
if (color[q[i].u] != color[q[i].v]) addedge(color[q[i].u], color[q[i].v]), OutDex[color[q[i].u]]++;
int ans = 0;
for (int i = 1; i <= Ctot; i++)
if (!OutDex[i]){
if (ans){
printf("0\n");
return 0;
}
ans += val[i];
}
printf("%d\n", ans);
return 0;
}