#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<limits.h>
#include<cmath>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<functional>
#define iter(i,start,end) for(int (i)=(start);(i)<(end);(i)++)
using namespace std;
const int nmax=10000+5;
int n,m; //n城市个数\in[1,10000] m单向高速公路个数\in[1,100000]
vector<int>g[nmax];
int groupnum,time,ans; //groupnum强连通分量的数量(从1开始计数 time时间 ans强连通分量中点对的数量
bool onstack[nmax]; //是否在栈内
int group[nmax],low[nmax],dfn[nmax],member[nmax]; //low记录该点最早能回溯到的地方 dfn各点的时间戳 member[i]记录第i组有几个点【其实这个数组可以通过边遍历边记录ans省下来】
stack<int> s;
void init();
void tarjan(int cur);
int main()
{
//freopen("201509-4.txt","r",stdin);
while(scanf("%d %d",&n,&m)==2)
{
init();
while(!s.empty()) s.pop();
time=1;
iter(i,0,n){
if(!dfn[i])
tarjan(i);
}
iter(i,0,n)
member[group[i]]++;
sort(member+1,member+groupnum+1,greater<int>()); //【记录下是不是这么写的】
iter(i,1,groupnum+1){
if(member[i]>1)
ans+=member[i]*(member[i]-1)/2;
}
cout<<ans;
}
return 0;
}
void tarjan(int cur){
low[cur]=dfn[cur]=time++;
onstack[cur]=true; s.push(cur); //【记录】这几个stl的函数
iter(i,0,g[cur].size()){
int to=g[cur][i];
if(!dfn[to]){ //如果遍历过就不要进去了 不然dfn和low数组都会变化的
tarjan(to);
if(low[to]<low[cur]) //或者直接用Min(low[to],low[cur])代替
low[cur]=low[to];
}
else{
if(onstack[to] && dfn[to] < low[cur]) //在这里wa了半天 忘了判断dfn[to] < low[cur]了
low[cur]=dfn[to]; //如果直接用Min(low[cur],dfn[to])代替 就不会wa这么久了...吃了没读书的亏
}
}
if(low[cur]==dfn[cur]) //小环套大环也不怕
{
int tmp=-1,cnt=0; //tmp赋为-1是因为节点编号从0开始的
while(tmp!=cur){
tmp=s.top(); s.pop();
group[tmp]=groupnum;
onstack[tmp]=false;
cnt++;
}
groupnum++;
if(cnt>1) ans+=cnt*(cnt-1)/2; //如果强连通分量只由一个数组成,也不存在什么点对之说了
}
}
void init(){
memset(g,0,sizeof(g));
int u,v;
iter(i,0,m){
cin>>u>>v;
g[u-1].push_back(v-1);
}
groupnum=1,time=0,ans=0;
memset(onstack,0,sizeof(onstack));
memset(group,0,sizeof(group)); //0表示还没分组
memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn));
memset(member, 0, sizeof(cout));
}
201509-4 高速公路 tarjan强连通分量算法 O(V+E)
最新推荐文章于 2024-07-12 10:56:47 发布