原题链接:牛客网学术认可
Tarjan算法学习视频:b站
自作代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 50005;
const int maxm = 600005;
int n,m,x,y,ans = 0,cnt,tmp;
struct Edge
{
int to,next;
}e[maxm];
int head[maxm],tot=0;
void add(int &u,int &v)
{
e[++tot].to = v;
e[tot].next = head[u];
head[u] = tot;
}
int Time = 1;
int dfn[maxn]{0},low[maxn]{0},in_stack[maxn]{0};
int stack[maxn]{0},s = 0;
void Tarjan(int id)
{
stack[s++] = id;
in_stack[id] = 1;
dfn[id] = low[id] = Time++;
for(int i = head[id];i!=-1;i=e[i].next)
{
if(!dfn[e[i].to])
{
Tarjan(e[i].to);
low[id] = min(low[id],low[e[i].to]);
}
else if(in_stack[e[i].to])
low[id] = min(low[id],low[e[i].to]);
}
if(dfn[id] == low[id])
{
cnt = 0;
do
{
tmp = stack[--s];
in_stack[tmp] = 0;
cnt++;
}while(tmp!=id);
ans += cnt *(cnt - 1) / 2;
}
}
int main()
{
cin>>n>>m;
memset(head,-1,sizeof(head));
for(int i = 0 ;i < m ; i ++ )
{
cin>>x>>y;
add(x,y);
}
for(int i = 1; i <= n; i++)
if(!dfn[i])
Tarjan(i);
cout<<ans;
return 0;
}