【问题标题】:Finding cycle in the graph在图中找到循环
【发布时间】:2016-02-28 19:56:49
【问题描述】:

给定一个简单的无向图G=(V,E)V 的子集S

我们被告知S 的所有顶点都在G 中形成一个简单的循环(length |S|)。

现在,我们要找到那个精确的循环(或它的任何循环移位)(S 的所有顶点的序列)。我们怎样才能找到它?有什么办法吗?

我尝试了DFS/BFS,但它似乎无法正常工作。

例如:如果我们有 4 个顶点 A, B, C, D in G 并且边是 (A,C), (A,D), (B,C), (B,D)。让给S= {A, B, C, D}

那么我们的答案应该是ADBCA(或BCADB或其任何循环移位)。

【问题讨论】:

  • 在我看来,如果你稍微修改一下,dijkstra 就可以解决问题。您可以查看此链接:stackoverflow.com/questions/3911626/…
  • 你想在 G[S] 中找到一个哈密顿循环,这是 G 在 S 上的子图。这个问题是 NP 完全的。

标签: graph-theory graph-algorithm cycle


【解决方案1】:

首先,您需要迭代 S 中的所有节点。如果有任何节点的顶点少于两个,那么您将找不到这样的循环。然后,您需要生成包含所有节点的回溯路径,检查每个节点是否在最后一个节点和第一个节点之间存在顶点。如果你找到了这样的路径,那么你已经找到了这样的循环。如果没有,那么在您使用的节点集中没有这样的循环。

【讨论】:

    【解决方案2】:

    我在 c++ 中使用邻接矩阵编写了一个解决方案,邻接列表解决方案也应该以相同的方式工作,因为我们知道这是一个简单的循环,我们可以从任何顶点开始并开始搜索可能的路径,即只包含我们想要的节点,如果我们找到相应长度的路径我们存储它,否则搜索直到找到一个。

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int G[100][100], n, m, S[100], sz;
    int ans[100], curr[100], vis[100];
    bool fd = false;
    
    void solve(int start, int len){
        vis[start] = 1;
        curr[len] = start;
        if(len == m-1){
            fd = true;
            for(int i = 0;i <= m;i++) ans[i] = curr[i];return;
        }
        for(int i = 0;i < n;i++){
            if(G[start][i] == 1 && vis[i] == 0 && S[i] == 1){
                solve(i, len+1);
            }
        }
        vis[start] = 0;
    }
    
    int main(){
        cin >> n >> sz;
        int p, q;
        for(int i = 0;i < sz;i++){
            cin >> p >> q;G[p][q] = 1;G[q][p] = 1;
        }
        cin >> m;
        for(int i = 0;i < m;i++){
            cin >> p;S[p] = 1;
        }
        for(int i = 0;i < n;i++){
            if(S[i] == 1){
                solve(i, 0);
                break;
            }
        }
        if(fd == false){
            cout << "No such path" << endl;
        }else{
            for(int i = 0;i < m;i++){
                cout << ans[i] << " ";
            }cout << endl;
        }
    return 0;
    }
    

    ideone 上的解决方案链接:https://ideone.com/FVTyJX

    【讨论】:

    • 嘿!你的代码的时间复杂度是多少?是多项式吗?
    • 你的代码是如何多项式的?您正在寻找所有可能的路径?它的 O(n^n),其中 n 是 S 中的顶点数。您正在使用回溯
    • 是的,你是对的,它不是多项式,我将删除我之前的评论。正如问题的 cmets 所述,这是寻找汉密尔顿循环的问题:en.wikipedia.org/wiki/…
    猜你喜欢
    • 2021-08-04
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 2012-07-03
    • 2016-01-30
    • 1970-01-01
    • 2016-03-10
    • 2020-11-06
    相关资源
    最近更新 更多