//#include <bits/stdc++.h>
#include<iostream>
#include<stack>
using namespace std;
#define M (INT_MAX)
#define PRINT_ARRAY(a,n) do{for(int i = 0; i < n; i++) cout<<a[i]<<"|"; cout<<endl;}while(0)
/**********************************************
1 → 0 → 3
↑ ↙ ↓
2 4
3 → 4 ← 6 → 2
↑↓ ↓ ↗ ↓ ↙↑
7 → 5 → 0 → 1
**********************************************/
#define V (5)
int g[V][V] =
{
{0,0,1,1,0},
{1,0,0,0,0},
{0,1,0,0,0},
{0,0,0,0,1},
{0,0,0,0,0}
};
//#define V (8)
//int g[V][V] =
//{ // 0 1 2 3 4 5 6 7
// {0,1,0,0,0,0,0,0},
// {0,0,1,0,0,0,0,0},
// {1,0,0,0,0,0,0,0},
// {0,0,0,0,1,0,0,1},
// {0,0,0,0,0,1,0,0},
// {1,0,0,0,0,0,1,0},
// {1,0,1,0,1,0,0,0},
// {0,0,0,1,0,1,0,0}
//};
/**********************************************
强连通分量 strongly connected component
**********************************************/
void tarjan_dfs(int curIndex, int dfn[], int low[], stack<int>& s, bool in_stack[])
{
static int time = 1;
dfn[curIndex] = low[curIndex] = time++;
s.push(curIndex);
in_stack[curIndex] = true;
for (int i = 0; i < V; i++)
{
if (g[curIndex][i])
{
if (0 == dfn[i])
{
tarjan_dfs(i, dfn, low, s, in_stack);
low[curIndex] = min(low[curIndex], low[i]);
}
else if (in_stack[i])
low[curIndex] = min(low[curIndex], dfn[i]);
}
}
int a = dfn[curIndex];
int b = low[curIndex];
if (dfn[curIndex] == low[curIndex])
{
int tmp;
do
{
tmp = s.top(); s.pop();
in_stack[tmp] = false;
cout << tmp << "-";
} while (tmp != curIndex);
cout << endl;
}
}
void scc_tarjan()
{
int dfn[V] = { 0 }, low[V] = { 0 };
bool in_stack[V] = { false };
stack<int> s;
for (int i = 0; i < V; i++)
if (!dfn[i])
tarjan_dfs(i, dfn, low, s, in_stack);
}
int main()
{
scc_tarjan();
return 0;
}
scc:强连通分量问题
简单理解为人相互认识的问题
例如:0认识2,2认识1,到1 的时候,1发现认识0,把自身的low(追溯值)变为和0的low值一样,同时回溯告诉2也更新一下low值;
后来0还认识3,3认识4;
输出朋友圈为4;3;1 2 0;三组