c++ - 寻找最短的周期,包括一个特定的边缘

标签 c++ graph shortest-path directed-graph weighted-graph

嗨,我想解决这个网站http://rosalind.info/problems/cte/上的“通过给定边缘的最短循环”问题。
假设我们的特定优势(这是我们在此问题中的第一优势)为“E”。
我写了一个程序来解决这个问题,我的算法是在'E'的end_node上使用DFS,直到遇到'E'的start_node。对于该网站上给出的示例,它工作正常,但是当我使用大量数据时,它就进入循环。
我尝试了许多简单的有向图示例,但没有发现为什么会循环。
有人可以告诉我是否存在循环吗?

这是我的程序:

#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;
}

最佳答案

首先,您应该使用BFS而非DFS来计算未加权图中的最短路径。

其次,要弄清楚代码的工作原理几乎是不可能的。如果您想获得有意义的答案,建议您清理代码。这里有一些指针:

  • 请使用描述变量的含义的变量名。像std::vector<…> vec这样的变量名使您的代码很难理解。
  • 添加一些注释,以告诉我们您的代码在哪里做什么。
  • 请不要使用#define pb push_back这样的思想。这使得几乎所有不是您的人都无法阅读您的代码。
  • 您使用了很多不必要的指针/堆分配(并且不对它们进行delete。)示例为vecrecstack(将其作为std::vector<bool>……)
  • 使用std::numeric_limits而不是定义自己的maxn等。
  • 使用.push_back(std::make_pair(a,b))代替.emplace_back(a,b)
  • 关于c++ - 寻找最短的周期,包括一个特定的边缘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51643781/

    相关文章:

    python - 在python中生成有向词图

    Java检测循环有向图

    找到多个短路径的算法

    algorithm - 最短路径练习

    c++ - 尝试使用 Qt 和 VTK 显示 DICOM 文件时出现未定义的引用问题

    c++ - 自动类生成器

    c# - 如何使用 native 应用程序 C# XAML 在 Azure AD 上创建新用户?

    algorithm - 将一种 Assets 转换为另一种 Assets 的最佳算法

    c++ - 如何验证用户将字符串输入到 std::cin 中?

    c++ - QT Creator 的 LNK4099 链接器警告