tarjan板子题
要注意的一点就是用do-while和while,count应该会相差1。
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <string.h>
using namespace std;
const int maxn =200001;
stack<int> s;
vector<int> grap[maxn];
int cnt, n,indexx,t, m, a, b, ans = 0;
int dfn[maxn], low[maxn], instack[maxn*2], vis[maxn];
void tarjan(int v)
{
low[v] = dfn[v] = ++indexx;
s.push(v);
vis[v] = 1;
instack[v] = 1;
for(int i = 0 ; i < grap[v].size(); ++i)
{
int w = grap[v][i];
if(!vis[w])
{
tarjan(w);
low[v] = min(low[v], low[w]);
}
else if(instack[w])
{
low[v] = min(low[v], dfn[w]);
}
}
int u;
cnt = 0;
if(low[v] == dfn[v])
{
do{
u = s.top();
cnt++;
instack[u] = 0;
s.pop();
}while(u != v);
}
if(cnt > 1)
ans += cnt * (cnt-1) / 2;
}
int main()
{
cin>>n>>m;
memset(vis, 0, sizeof(vis));
for(int i = 1 ; i <= m ; ++i)
{
cin>>a>>b;
grap[a].push_back(b);
}
for(int i = 1; i <= n ; ++i)
{
if(!vis[i])
tarjan(i);
}
cout<<ans;
return 0;
}