Как определить, имеет ли граф неуникальную топологическую сортировку

Я создал программу, которая упорядочивает граф по топологической сортировке по заданной диаграмме. Я определил 3 результата:

  • ok
  • существующие циклы
  • недостающая информация

Вывод первых двух пунктов правильный, а третьего нет. Например, для графа с 4 вершинами и ребрами: 1->2; 3->1; 3->4; 4->2, результат, который я получил: 3 1 4 2... неправильно! То, что известно, недостаточно, чтобы сделать такой вывод. Любые подсказки или помощь приветствуются, заранее спасибо.

#include<bits/stdc++.h>
using namespace std;

class Graph{
    int V;
    list<int> *adj;
    public:
        Graph(int V);
        void addEdge(int u, int v);
        void topologicalSort();
};

Graph::Graph(int V){
    this->V = V;
    adj = new list<int>[V];
}

void Graph::addEdge(int u, int v){
    adj[u].push_back(v);
}

void Graph::topologicalSort(){
    vector<int> in_degree(V, 0);
    for (int u=0; u<V; u++){
        list<int>::iterator itr;
        for (itr = adj[u].begin(); itr != adj[u].end(); itr++)
             in_degree[*itr]++;}
    queue<int> q;
    for (int i = 0; i < V; i++)
        if (in_degree[i] == 0)
            q.push(i);
    int cnt = 0;
    vector <int> top_order;
    while (!q.empty()){
        int u = q.front();
        q.pop();
        top_order.push_back(u);
        list<int>::iterator itr;
        for (itr = adj[u].begin(); itr != adj[u].end(); itr++)
            if (--in_degree[*itr] == 0)
                q.push(*itr);
        cnt++;}
    if (cnt != V){
        cout << "Existing cycle\n";
        return;}
    for (int i=1; i<(int)top_order.size(); i++)
        cout << top_order[i] << " ";
    cout << endl;
}

int main(){
    setbuf(stdout, NULL);
    int N, L, u, v;
    scanf("%d %d", &N, &L);
    Graph g(N+1);
    for (int i=1; i<=L; i++){
        scanf("%d %d", &u, &v);
        g.addEdge(u, v);
    }
    g.topologicalSort();
    return 0;
}

person sink    schedule 16.03.2017    source источник
comment
Пожалуйста, прочитайте это, это действительно поможет: ericlippert.com/2014 /03/05/как отлаживать небольшие программы   -  person alexeykuzmin0    schedule 16.03.2017
comment
Спасибо, я знаю, что я сделал, я только прошу помощи, чтобы понять шаблон и создать способ его решения.   -  person sink    schedule 16.03.2017
comment
Что вы ожидаете? Ваш код (предположительно) даст правильную топологическую сортировку для данного орграфа. Однако вы говорите, что оба [3, 1, 4, 2] и [3, 4, 1, 2] действительны? Итак, вы хотите, чтобы алгоритм обнаруживал неуникальные заказы?   -  person gilleain    schedule 16.03.2017
comment
Большое спасибо за то, что вы сказали! Я хочу, чтобы, когда алгоритм обнаруживает неуникальные заказы, он выдавал недостаточную строку на выходе. Но как отличить уникальные заказы от неуникальных?   -  person sink    schedule 16.03.2017
comment
Какой вопрос? Вы говорите, что вывод неверен, но, учитывая ваш ввод, это похоже на топо-сортировку. Так что же делает это неправильно?   -  person Paul Hankin    schedule 16.03.2017
comment
Это потому, что я должен соблюдать критерий принятия, и для этого типа шаблона вывод должен быть недостаточным.   -  person sink    schedule 16.03.2017
comment
comment
Я изучу ваше решение. Беллоу @gilleain предложил мне посмотреть путь Гамильтина.   -  person sink    schedule 16.03.2017


Ответы (2)


Чтобы проверить, что конкретный граф имеет уникальную топологическую сортировку, по-видимому, достаточно проверить наличие гамильтонова пути в DAG. Цитирую википедию:

Если топологическая сортировка обладает тем свойством, что все пары последовательных вершин в порядке сортировки соединены ребрами, то эти ребра образуют направленный гамильтонов путь в DAG. Если гамильтонов путь существует, топологический порядок сортировки уникален; никакой другой порядок не учитывает края пути. И наоборот, если топологическая сортировка не образует гамильтонов путь, DAG будет иметь два или более допустимых топологических порядка, так как в этом случае всегда можно сформировать второй допустимый порядок, поменяв местами две последовательные вершины, которые не соединены ребром. друг другу. Следовательно, можно за линейное время проверить, существует ли уникальный порядок.

Поэтому вам просто нужно получить DAG для первой найденной сортировки и проверить, образует ли он путь, который посещает все вершины.

person gilleain    schedule 16.03.2017
comment
Спасибо, я изучу ваше решение. - person sink; 16.03.2017

В приведенном коде, если вы обнаружите, что выполняете два или более q.push() в результате одного q.pop(), то любая результирующая сортировка не будет уникальной. Проверка этого, вероятно, менее проблематична, чем проверка полученного DAG на гамильтонов путь.

Это то же условие, что обсуждалось в комментариях здесь: Определить, имеет ли ориентированный граф уникальный топологический порядок?

person Theo H    schedule 17.02.2021