您的位置:首页 > 其它

强连通分量Tarjan模板

2013-08-10 11:50 357 查看
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stack>
#include<vector>
#include<algorithm>

#define N 1000

using namespace std;

int pre
,lowlink
,sccno
,dfn_clock,scc_cnt;

stack<int> stk;

vector<int> G
;

void DFN(int u)
{
pre[u] = lowlink[u] = ++dfn_clock;  //时间戳
stk.push(u);
int i;
for(i=0;i<G[u].size();i++)
{
int v = G[u][i];
if(!pre[v])  //没有访问过
{
DFN(v);
lowlink[u] = min(lowlink[u],lowlink[v]);
}
else if(!sccno[v])  //被访问过,但是不是其他强连通图的组成
{
lowlink[u] = min(lowlink[u],pre[v]);
}
}
if(lowlink[u]==pre[u])  //发现一个强连通分量
{
scc_cnt++;  //强连通分量的个数计算
while(1)
{
int x = stk.top();
stk.pop();
sccno[x] = scc_cnt;
if(x==u)    break;
}
}
}

void find_scc(int n)
{
dfn_clock = scc_cnt = 0;
memset(sccno,0,sizeof(sccno));
memset(pre,0,sizeof(pre));
int i;
for(i=1;i<=n;i++)
if(!pre[i]) DFN(i);
}

int main()
{
int n,m;
scanf("%d%d",&n,&m);
int i;
for(i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
G[a].push_back(b);   //构造图
}
find_scc(n);  //查找强连通图
for(i=1;i<=n;i++)
printf("%d ",sccno[i]);
putchar(10);
return 0;
}

/*
//测试用图
6 8
1 3
3 5
5 6
3 4
4 6
4 1
1 2
2 4
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: