T a r j a n Tarjan Tarjan算法的裸题,只要判断强连通分量是否大 1 1 1就行了,如果大于就答案 + 1 +1 +1,最后输出就行了。
代码:
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
using namespace std;
int read()
{
int x = 0;
int f = 1;
char ch = getchar();
for(;!isdigit(ch);ch = getchar())
if(ch == '-')
f = -1;
for(;isdigit(ch);ch = getchar())
x = x * 10 + (ch ^ 48);
return x * f;
}
void print(int x)
{
if(x < 0)
{
putchar('-');
x = -x;
}
char ch = x % 10 + '0';
if(x > 9)
print(x / 10);
putchar(ch);
}
const int N = 10010,M = 50010;
struct edge
{
int to,nxt;
}e[M];
int head[N],cnt;
void add(int u,int v)
{
e[++cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt;
}
int n,m;
int dfn[N],low[N],dfs_clock,vis[N];
int num[N],color_num;
int ans;
stack<int> s;
void tarjan(int x)
{
dfn[x] = low[x] = ++dfs_clock;
s.push(x);
vis[x] = true;
for(int i = head[x];i;i = e[i].nxt)
{
int v = e[i].to;
if(!dfn[v])
{
tarjan(v);
low[x] = min(low[x],low[v]);
}
else
if(vis[v])
low[x] = min(low[x],dfn[v]);
}
if(dfn[x] == low[x])
{
color_num++;
while(s.top() != x)
{
int t = s.top();
s.pop();
num[color_num]++;
vis[t] = false;
}
s.pop();
num[color_num]++;
vis[x] = false;
}
}
int main()
{
int u;
n = read(),m = read();
for(int i = 1;i <= m;i++)
u = read(),add(u,read());
for(int i = 1;i <= n;i++)
if(!dfn[i])
tarjan(i);
for(int i = 1;i <= color_num;i++)
if(num[i] > 1)
ans++;
print(ans);
}