在图中查找循环

时间:2016-02-28 19:56:49

标签: graph-theory graph-algorithm cycle

我们获得了一个简单的无向图G=(V,E)S的{​​{1}}子集。

我们被告知V的所有顶点都在S中进行了一个简单的循环(length |S|)。

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

我尝试了G,但似乎没有正常工作。

例如:如果我们有4个顶点DFS/BFS且边是A, B, C, D in G。给出(A,C), (A,D), (B,C), (B,D)

然后我们的答案应为S= {A, B, C, D}(或ADBCA或其任何循环移位)。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

我在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