2

We are given a simple un-directed graph G=(V,E) and a subset S of V.

We are told that all the vertices of S are making a simple cycle (of length |S|) in G.

Now, we are to find that exact cycle (or its any cyclic shift) (a sequence of all vertices of S). How can we find it ? Any approach ?

I tried DFS/BFS but it does not seem working fine.

For example: if we have 4 vertices A, B, C, D in G and edges are (A,C), (A,D), (B,C), (B,D). Let given S= {A, B, C, D}

Then our answer should be ADBCA (or BCADB or its any cyclic shift).

Jamie Eltringham
  • 810
  • 3
  • 16
  • 25
Sushil Verma
  • 659
  • 9
  • 23
  • in my opinion dijkstra would do the trick if you modify it a bit. you might check this link: http://stackoverflow.com/questions/3911626/find-cycle-of-shortest-length-in-a-directed-graph-with-positive-weights – Jodn Feb 28 '16 at 20:03
  • 1
    You want to find a Hamiltonian cycle in G[S], the subgraph of G induced on S. This problem is NP-complete. – Valentas Feb 29 '16 at 11:28

2 Answers2

1

First, you need to iterate all your nodes in S. If there are any nodes having less than two vertices, then you will not find such a cycle. Then, you need to generate with backtracking paths containing all nodes, checking for each whether there is a vertice between the last and the first node. If you find such a path, then you have found such a cycle. If not, then there is no such cycle in the node set you work with.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
1

I have written a solution using adjacency matrix in c++, a adjacency list solution should also work in the same way, since we know that it is a simple cycle we can start from any vertex and start searching for a possible path, that contains only the nodes that we want, if we find the path of corresponding length we store it, or else search untill we find one.

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

Link to solution on ideone : https://ideone.com/FVTyJX

uSeemSurprised
  • 1,826
  • 2
  • 15
  • 18
  • Hey! what is the time complexity of your code? Is it polynomial? – Sushil Verma May 21 '16 at 20:15
  • How your code is polynomial? you are searching for all the possible paths? Its O(n^n), where n is the number of vertices in S. You are using backtracking – Sushil Verma Dec 07 '16 at 11:21
  • Yes, you are right it is not polynomial, I will delete my earlier coment. As stated in the comments to the question it is the problem of finding a hamiltonian cycle : https://en.wikipedia.org/wiki/Cycle_(graph_theory)#Covering_graphs_by_cycles – uSeemSurprised Dec 07 '16 at 11:43