Консультация № 186373
15.06.2012, 13:30
101.02 руб.
0 20 1
Здравствуйте! Прошу помощи в следующем вопросе:

В курсовой работе по дискретной математике присутствует такое задание:

1.Изучить алгоритм
2.Составить программу алгоритма
3.Отладить тестовые примеры

4.Провести оценку сложности алгоритма
5.Составить прикладную задачу, для решения которой используется данный алгоритм

Алгоритм "Нахождение компонент сильной связности графа"

Я не умею писать программы, но задание нужно сдать.Очень прошу помощи у экспертов портала, помогите, пожалуйста, написать программу к этому алгоритму!( на языке Си )

Преподаватель не требовательный, в программировании не разбирается, проверяет только работоспособность программы.

Обсуждение

давно
Посетитель
7438
7205
15.06.2012, 23:47
общий
Какой именно алгоритм Вас интересует?
Есть, как минимум, три: Косарайю, Габова и Тарьяна
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
15.06.2012, 23:52
общий
Адресаты:
Вы меня простите, но у меня больше в задании ничего не указано... Наверное, лучше сделать тот, который попроще, главное, чтобы искались компоненты сильной связности
Единственное - написано "Кофман А. Введение в прикладную комбинаторику" - наверное, литература.
давно
Профессор
230118
3054
16.06.2012, 14:47
общий
это ответ
Здравствуйте, Григорий Сальнечников!

Описываемый здесь алгоритм был предложен независимо Косараю (Kosaraju) и Шариром (Sharir) в 1979 г. Это очень простой в реализации алгоритм, основанный на двух сериях поисков в глубину, и потому работающий за время O(n+m).

На первом шаге алгоритма выполняется серия обходов в глубину, посещающая весь граф. Для этого мы проходимся по всем вершинам графа и из каждой ещё не посещённой вершины вызываем обход в глубину. При этом для каждой вершины v запомним время выхода tout[v]. Эти времена выхода играют ключевую роль в алгоритме, и эта роль выражена в приведённой ниже теореме.
Определения

Ориентированный ациклический граф (directed acyclic graph) — это орграф, не содержащий направленных циклов.
Алгоритм
1. Инвертируем ребра исходного орграфа.
2. Запускаем поиск в глубину на этом обращенном графе. В результате получаем вектор обхода.
3. Запускаем поиск в глубину на исходном графе, в очередной раз выбирая непосещенную вершину с максимальным номером в векторе, полученном в п.2.
4. Полученные деревья из п.3, и являются сильно связными компонентами.

Код:
// 186373.cpp : Defines the entry point for the console application.

#include <vector>
#include <iostream>
using namespace std;

vector < vector<int> > g, gr; //g - graf gr transponirovanny graf
vector<char> used; //pometki vershin
vector<int> order, component;

void dfs1 (int v) {
used[v] = true;
int n=g[v].size();
for (size_t i=0; i<n; ++i)
if (!used[ g[v][i] ])
dfs1 (g[v][i]);
order.push_back (v);
}

void dfs2 (int v) {
used[v] = true;
component.push_back (v);
for (size_t i=0; i<gr[v].size(); ++i)
if (!used[ gr[v][i] ])
dfs2 (gr[v][i]);
}

int main() {
int n;

//... чтение n ...
cout<<"vvedite kolichestvo vershin"<<endl;
cin >>n;
g.resize(n);
gr.resize(n);
for (;;) {
int a, b;
// ... чтение очередного ребра (a,b) ...
cout<<"vvedite rebro"<<endl;
cin >>a;

if (a==0) break;
if (a>n|| a<0) { cout<<"nepravilny index"<<endl; continue;}
cin >>b;
if (b>n || b<=0) { cout<<"nepravilny index"<<endl; continue;}
g[a-1].push_back (b-1);
gr[b-1].push_back (a-1);
}

used.assign (n, false);
for (int i=0; i<n; ++i)
if (!used[i])
dfs1 (i);
used.assign (n, false);
for (int i=0; i<n; ++i) {
int v = order[n-1-i];
if (!used[v]) {
dfs2 (v);
// ... вывод очередной component ...
cout << "componenta silnoy svyaznosti"<< endl;
for (int k=0; k<component.size(); ++k) {
cout << component[k]+1;
}
cout << endl;
component.clear();
}
}

}
Неизвестный
16.06.2012, 22:21
общий
Адресаты:
Огромное спасибо за ответ!Насколько я понял, программа написана на языке С++?А в какой среде разработки ее компилировать?Просто в Visual Studio 10 выдает фатальную ошибку
давно
Профессор
230118
3054
16.06.2012, 22:25
общий
я писала в Visual Studio express. Создайте консольное приложение и уберите опцию precompiled headers
Неизвестный
18.06.2012, 14:41
общий
Адресаты:
У меня после того, как ввожу ребра, выскакивает ошибка Debug Assertion Failed! Expression: vector subscript out of range..
давно
Профессор
230118
3054
18.06.2012, 14:43
общий
Нумерация должна быть от 1. Для конца ввода пишите 0
Неизвестный
18.06.2012, 17:43
общий
Адресаты:
Простите, пожалуйста, но я не понял
В смысле нумерация от 1?Сначала вводим количество вершин, а потом ребра, верно?Например, ввожу 3, а затем ввожу 12(энтер)13(энтер) и вылезает ошибка
давно
Профессор
230118
3054
18.06.2012, 20:59
общий
У меня работает нормально
Неизвестный
18.06.2012, 22:03
общий
Адресаты:
Странно, еще у двух людей вылетает после ввода 2го ребра..У одного MVS 08, у другого dev C++.Ну ладно, спасибо Вам
Неизвестный
18.06.2012, 22:08
общий
Адресаты:
http://dump.ru/file/5772464
Вот что показывает
давно
Профессор
230118
3054
18.06.2012, 22:55
общий
А почему вы вводите числа 12 и 13? Естественно, надо писать пробелы 1 2
1 3
Как программа поймет, что Вы хотели ввести ребро 12, а не вершину 12, которой не может быть в графе из 3 вершин?
Неизвестный
18.06.2012, 23:40
общий
Адресаты:
Точно!
Теперь вроде работает все, но я не успеваю посмотреть результат, тк окно закрывается.Не нужна функция getch()?
давно
Профессор
230118
3054
19.06.2012, 00:36
общий
Запускайте в режиме without debugging
Неизвестный
19.06.2012, 01:23
общий
Адресаты:
Я не могу найти такого пункта... у меня в Debug нет пункта Start without debugging
давно
Профессор
230118
3054
19.06.2012, 01:29
общий
I had a similar with C# problem and I found the following solution: In the "Tools/Settings" Menu I checked the "Expert Settings" and the Start Without Debugging showed up again
Неизвестный
19.06.2012, 14:58
общий
Адресаты:
Спасибо, нашел
Но ведь черное окно все равно пропадает после ввода 0
Я ввожу 3 ребра(сначала 1 2, потом 1 3, потом 2 3), а затем жму 0, чтобы закончить ввод.Я успеваю увидеть, что выводятся компоненты связности, но ведь окно то закрывается
давно
Посетитель
7438
7205
19.06.2012, 15:03
общий
Что за проблемы? Есть необходимость, добавьте getch() Кто мешает?
Не забудьте только подключить conio.h
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.06.2012, 17:02
общий
Адресаты:

Уже добавил, все получилось, спасибо !

Программа заработала как нужно, но можно пару вопросов по реализации?
1)Что значит "обход в глубину"?
2)Что собой представляет "вектор обхода"?
Заранее спасибо!
Неизвестный
20.06.2012, 20:14
общий
Адресаты:
Все, уже не нужно!
Я Вам очень признателен за помощь!Спасибо!
Форма ответа