版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41661919/article/details/85646502
直接上模板把,有些地方还是不好理解啊。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include<algorithm>
#include <set>
#include <queue>
#include <stack>
#include<vector>
#include<map>
#include<ctime>
#define ll long long
using namespace std;
const int N=10010;
const int M=50010*2;
int head[N];
int ver[M];
int Next[M];
int n,m,tot;
void add(int x,int y)
{
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
int dfn[N],low[N];
int stackk[N],ins[N],c[N];
vector<int> scc[N];
int num=0;
int top;//指针
int cnt;//强联通分量标号
void tarjan(int x)
{
dfn[x]=low[x]=++num;
stackk[++top]=x;
ins[x]=1;
for(int i=head[x];i;i=Next[i])
{
int y=ver[i];
if(!dfn[y])
{
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(ins[y])
{
low[x]=min(low[x],low[y]);
}
}
if(dfn[x]==low[x])
{
cnt++;
int y;
do
{
y=stackk[top--];
ins[y]=0;
c[y]=cnt;
scc[cnt].push_back(y);
}while(x!=y);
}
}
int hc[N];
int vc[M];
int nc[M];
int tc;
void add_c(int x,int y)
{
vc[++tc]=y;
nc[tc]=hc[x];
hc[x]=tc;
}
int main()
{
while(cin>>n>>m)
{
for(int i=1;i<=m;++i)
{
int x,y;
cin>>x>>y;
add(x,y);
}
for(int i=1;i<=n;++i)//求 森林的 的强联通够分量,主要求c【】数组和scc数组;
{
if(!dfn[i])tarjan(i);
}
//原图缩点
for(int x=1;x<=n;++x)
for(int i=head[x];i;i=Next[i])
{
int y=ver[i];
if(c[x]==c[y])continue;
add_c(c[x],c[y]);
}
}
return 0;
}
The end;