Я пытаюсь реализовать версию алгоритма Тарьяна, используя c ++, чтобы найти связи между различными сильно связанными графами.
void tarjanDFS(int i)
{
Discovery[i] = ++Indices;
Low[i] = Indices;
Stack.push(i);
visited[i] = true;
std::list<int>::iterator j;
for (j = graf[i].begin(); j != graf[i].end(); j++)
{
int w = (*j);
if (Discovery[w] == 0)
{
tarjanDFS(w);
Low[i] = min(Low[i], Low[w]);
}
else if (visited[w])
{
Low[i] = min(Low[i], Discovery[w]);
}
}
if (Low[i] == Discovery[i])
{
int w = 0;
do
{
w = Stack.top(); Stack.pop();
//component[w] = numComponents;
visited[w]=false;
} while (i != w && !Stack.empty());
numComponents++;
}
}
void Tarjan()
{
Indices = 0;
while (!Stack.empty())
Stack.pop();
for (int i=vertices;i>0;i--)
visited[i] = Low[i] = Discovery[i] = 0;
numComponents = 0;
for (int i=vertices;i>0;i--)
if (Discovery[i] == 0)
tarjanDFS(i);
}
Например. Для ввода пар (u v), где U — источник, а V — судьба.
1 2
2 3
3 1
2 4
5 4
4 5
3 5
3 6
6 5
Выход для связей между различными SCC будет
2 4
3 5
3 6
6 5
Я успешно реализовал эту часть с помощью Tarjan, проблема в том, что я хочу выводить эти ссылки, используя корень каждого SCC, а не элемент, с которого идет ссылка.
Правильный вывод в действительности должен быть:
1 4
1 4
1 6
6 4
Как я могу реализовать такую вещь внутри tarjan, которая позволяет мне найти корень SCC каждого элемента или заменить элемент его корнем? Я думаю, что, возможно, самым простым способом было бы назвать или сгруппировать каждый SCC с его корневым значением и перейти оттуда
Задача ещё не решена.
Других решений пока нет …