Найти кратчайший цикл, который включает в себя определенное ребро

Привет, я хотел решить проблему "кратчайшего цикла через заданное ребро", которая находится на этом сайте http://rosalind.info/problems/cte/. предположим, что наше конкретное ребро (то есть наше первое ребро в этой задаче) будет "E". я написал программу для решения этой проблемы, и мой алгоритм состоит в том, чтобы использовать DFS на end_node 'E', и это продолжается до встречи start_node 'E'. он отлично работает для примера, приведенного на этом сайте, но когда я использовал большие данные, он зацикливается. Я попробовал много примеров простых ориентированных графов, и я не нашел, почему это идет в цикл. Может кто-нибудь показать мне, если есть в любом случае, что это идет в петлю?

вот моя программа:

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <list>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <stack>


using namespace std;

#define ll long long int
#define pb push_back
#define mk make_pair

const ll maxn = 1e5 + 3;
const ll inf = 1e12 + 10;

vector <ll> cost;

void is_cyclic(int i, bool * recstack,ll cnt,vector <pair<ll,ll>> * vec,ll ind) {
    recstack[i] = true;
    vector <pair<ll, ll>>::iterator it = vec[i].begin();
    for (; it != vec[i].end(); it++) {
        if (it->first == ind) {
            cnt += it->second;
            cost.pb(cnt);
        }
        else {
            if (recstack[it->first] == false) {
                is_cyclic(it->first, recstack, cnt + it->second, vec, ind);
            }
        }
    }
    recstack[i] = false;
}

int main() {
    ll k;
    //file >> k;
    //while (k--) {
        ll n, m;
        cin >> n >> m;
        ll s;
        vector <pair<ll, ll>> * vec;
        vec = new vector<pair<ll, ll>>[n];
        for (int j = 0; j < m; j++) {
            ll a, b, c;
            cin >> a >> b >> c;
            if (j == 0) {
                s = a - 1;
            }
            vec[a - 1].pb(mk(b - 1, c));
        }
        bool * recstack = new bool[n];
        for (int j = 0; j < n; j++) {
            recstack[j] = false;
        }
        ll cnt = 0;
        pair <ll, ll> p;
        p = vec[s][0];
        cnt += p.second;
        recstack[s] = true;
        is_cyclic(p.first, recstack, cnt, vec,s);
        if (cost.size() == 0) {
            cout << -1 << " ";
        }
        else {
            sort(cost.begin(), cost.end());
            cout  << cost[0] << " ";
        }
        cost.clear();
    //}
    return 0;
}

1 ответ

Во-первых, вы должны использовать BFS, а не DFS, для вычисления кратчайших путей в невзвешенных графах.

Во-вторых, почти невозможно понять, как именно работает ваш код. Если вы хотите получить содержательные ответы, я бы порекомендовал очистить ваш код. Вот несколько указателей:

  • Пожалуйста, используйте имена переменных, которые описывают, что переменная делает / означает. Названия переменных как std::vector<…> vec сделать ваш код очень сложным для понимания.
  • Добавьте несколько комментариев, чтобы рассказать нам, что делает ваш код.
  • Пожалуйста, не используйте думает, как #define pb push_back, Это делает практически невозможным для всех, кто не вы, читать ваш код.
  • Вы используете много ненужных указателей / распределений кучи (и вы не делаете delete их.) Примеры vec или же recstack (сделать это std::vector<bool>...)
  • использование std::numeric_limits вместо определения своего maxn и т.п.
  • Вместо .push_back(std::make_pair(a,b))использовать .emplace_back(a,b)
Другие вопросы по тегам