#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 10005
#define M 100005
int n,m;
int h[N],e[M],ne[M];
int idx;
int sta[N];
int top;
int ans;
int indx;
int vis_sta[N];
int low[N],dfn[N];
void add(int u,int v)
{
e[idx]=v;
ne[idx]=h[u];
h[u]=idx++;
}
void tarjan(int u)
{
dfn[u]=low[u]=++indx;
sta[++top]=u;
vis_sta[u]=1;
for(int i=h[u];~i;i=ne[i])
{
int v=e[i];
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}else if(vis_sta[v])
{
low[u]=min(low[u],dfn[v]); //表示属于起点为v的环路,!!注意此处改成Low[v]在此题也能过
}
}
if(dfn[u]==low[u]) //强连通分量的根
{
int y;
int cnt=0;
do{
y=sta[top--];
vis_sta[y]=0;
cnt++;
}while(y!=u);
ans+=cnt*(cnt-1)/2;
}
}
int main()
{
cin>>n>>m;
memset(h,-1,sizeof(h));
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
cout<<ans;
return 0;
}
CCF-CSP201509-4 高速公路 强连通分量 Tarjan 算法
最新推荐文章于 2021-04-01 14:15:10 发布