CCF 认证4

时间:2023-03-09 21:49:14
CCF 认证4

题意:求强联通分量

Tarjan算法

 #include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<map>
#define clc(a,b) memset(a,b,sizeof(a))
typedef long double ld;
typedef long long ll;
const int N = ;
const double eps=1e-;
const int inf=-;
const int maxn=1e5+;
const int num=;
const double Pi=acos(-);
using namespace std; struct gragh
{
int to;
int next;
} V[num]; bool instack[num]= {false};
int low[num]= {},DFN[num]= {},Stap[num]= {},Belong[num]= {};
int answer=;
int Dindex,stop,Bcnt;
int head[num];
int edge; void add(int a,int b)
{
V[edge].to=b;
V[edge].next=head[a];
head[a]=edge++; }
void tarjan(int u)
{
int v;
DFN[u]=low[u]=++Dindex;
instack[u]=true;
Stap[stop++]=u;
for(int i=head[u]; i!=-; i=V[i].next)
{
v=V[i].to;
if(!DFN[v])
{
tarjan(v);
if(low[v]<low[u])
low[u]=low[v];
}
else if(instack[v]&&DFN[v]<low[u])
low[u]=DFN[v];
}
if(DFN[u]==low[u])
{
int sum=;
Bcnt++;
do
{
v=Stap[--stop];
instack[v]=false;
Belong[v]=Bcnt;
sum++;
}
while(v!=u);
cout<<sum<<endl;
if(sum!=)
answer+=(sum*(sum-))/;
}
}
void solve(int N)
{
stop=Bcnt=Dindex=;
// clc(DFN,0);
for(int i=; i<=N; i++)
if(!DFN[i])
tarjan(i);
} int main()
{
int n,m;
int a,b;
cin>>n>>m;
clc(head,-);
edge=;
for(int i=; i<m; i++)
{
cin>>a>>b;
add(a,b);
}
solve(n);
cout<<answer<<endl;
return ;
}