题解【洛谷P2863】 [USACO06JAN]牛的舞会The Cow Prom
题解
\(Tarjan\)板子题。
统计出大小大于\(1\)的强连通分量数量输出即可。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#define gI gi
#define itn int
#define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
using namespace std;
inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
return f * x;
}
int n, m, tot, head[200003], nxt[200003], ver[200003], low[200003], dfn[200003], num, sum, ans, sy[200003], ys[200003], kok;
int sta[200003], vis[200003], cnt;
inline void add(int u, int v)
{
ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}
void Tarjan(int u)
{
dfn[u] = low[u] = ++num, sta[++cnt] = u, vis[u] = 1;
for (int i = head[u]; i; i = nxt[i])
{
int v = ver[i];
if (!dfn[v])
{
Tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (vis[v]) low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u])
{
++kok;
int y = -1;
do
{
y = sta[cnt];
vis[y] = 0;
sy[y] = kok;
++ys[kok];
--cnt;
} while (y != u);
}
}
int main()
{
//File("P2863");
n = gi(), m = gi();
for (int i = 1; i <= m; i+=1)
{
int u = gi(), v = gi();
add(u, v);
}
for (int i = 1; i <= n; i+=1) if (!dfn[i]) Tarjan(i);
for (int i = 1; i <= kok; i+=1)
{
if (ys[i] > 1) ++ans;
}
printf("%d\n", ans);
return 0;
}