分享该博主的博客: http://blog.csdn.net/lishuhuakai/article/details/50346129
附上别处引用的代码:
#include "Stdafx.h"
#include <iostream>
#include <stack>
using namespace std;
#define MAX_VERTEX_SIZE 10001
struct EdgeNode{
int vertex;
EdgeNode *nextArc;
};
struct VerTexNode{
EdgeNode* firstArc;
};
struct Graph{
int n,e;
VerTexNode vNode[MAX_VERTEX_SIZE];
};
int time = 0;
int low[MAX_VERTEX_SIZE];
int dfn[MAX_VERTEX_SIZE];
int visited[MAX_VERTEX_SIZE];
int inStack[MAX_VERTEX_SIZE];
int ans = 0;//存储运算结果
stack<int> st;
Graph graph;
void initeGraph(int n,int m)
{
for(int i = 1;i<=n;i++)
{
graph.vNode[i].firstArc = NULL;
}
graph.n = n;
graph.e = m;
}
//头插法建立图
void creatGraph(int s,int v)
{
EdgeNode *edgeNode = new EdgeNode;
edgeNode->vertex = v;
edgeNode->nextArc = graph.vNode[s].firstArc;
graph.vNode[s].firstArc = edgeNode;
}
int min(int a,int b)
{
if(a>b)
return b;
else
return a;
}
void trajan(int u)
{
dfn[u] = low[u] = time++;
st.push(u);
visited[u] = 1;
inStack[u] = 1;
EdgeNode *edgePtr = graph.vNode[u].firstArc;
while(edgePtr !=NULL)
{
int v = edgePtr->vertex;
if(visited[v] == 0)
{
trajan(v);
low[u] = min(low[u],low[v]);
}
/*之前没有对inStack[v]进行判断,又可能当前的v已经出栈了,这个时候就会出错。
所以导致我的最后得分为80分。
加上if条件,最后为满分。
切记!切记!切记!!!
*/
else if(inStack[v] == 1)
{
low[u] = min(low[u],dfn[v]);
}
edgePtr = edgePtr->nextArc;
}
int result = 0;
if(dfn[u] == low[u])
{
int vtx;
//cout<<"set is: ";
do{
result++;
vtx = st.top();
st.pop();
inStack[vtx] = 0;//表示已经出栈
/* cout<<vtx<<' ';*/
}while(vtx !=u );
if(result > 1)
{
ans += result*(result-1)/2;
}
result = 0;
}
}
int main()
{
int n,m;
int s,a;
cin>>n>>m;
initeGraph(n,m);
for(int i = 1;i<=n;i++)
{
visited[i] = 0;
inStack[i] = 0;
dfn[i] = 0;
low[i] = 0;
}
for(int j = 1;j<=m;j++)
{
cin>>s>>a;
creatGraph(s,a);
}
for(int i =1;i<=n;i++)
if(visited[i] == 0)
trajan(i);
cout<<ans<<endl;
return 0;
}
#include<iostream>
using namespace std;
#include<string.h>
#include<algorithm>
int n,m;
int head[10010],stackn[10010],DFN[10010],Low[10010];
int Belong[10010],instack[10010],cnt,top,f,scnt;
struct node
{
int e,next;
}edge[100010];
void add(int s,int e)
{
edge[f].e=e;
edge[f].next=head[s];
head[s]=f++;
}
void tarjan(int s)
{
int t,k,i;
DFN[s]=Low[s]=++cnt;
stackn[top++]=s;
instack[s]=1;
for(i=head[s];i!=-1;i=edge[i].next)
{
k=edge[i].e;
if(!DFN[k])
{
tarjan(k);
Low[s]=min(Low[k],Low[s]);
}
else if(instack[k])
{
Low[s]=min(Low[s],DFN[k]);
}
}
if(Low[s]==DFN[s])
{
scnt++;
do
{
t=stackn[--top];
Belong[t]=scnt;
instack[t]=0;
}
while(s!=t);
}
}
int main()
{
int i,j,a,b,v[10010];
cin>>n>>m;
f=1;
memset(head,-1,sizeof(head));
memset(v,0,sizeof(v));
for(i=0;i<m;i++)
{
cin>>a>>b;
add(a,b);
}
memset(DFN,0,sizeof(DFN));
for(i=1;i<=n;i++)
{
if(!DFN[i])
tarjan(i);
}
for(i=1;i<=n;i++)
v[Belong[i]]++;
long long sum=0;
for(i=0;i<=n;i++)
{
if(v[i]>1)
sum=sum+v[i]*(v[i]-1)/2;
}
cout<<sum<<endl;
return 0;
}