📌  相关文章
📜  检查仅 S 和 T 重复的无向图中节点 S 和 T 之间是否存在循环

📅  最后修改于: 2022-05-13 01:57:54.172000             🧑  作者: Mango

检查仅 S 和 T 重复的无向图中节点 S 和 T 之间是否存在循环

给定一个有N个节点和两个顶点S & T的无向图,任务是检查这两个顶点之间是否存在循环,使得除了ST之外的其他节点在该循环中出现的次数不超过一次。如果存在则打印Yes ,否则打印No。

例子:

方法:

如果存在一条从 T 到 S 的路径,该路径没有用于从 S 到 T 的路径的任何顶点,则将始终存在一个循环,使得除ST之外的其他节点不会出现多次。现在,要解决问题,请按照以下步骤操作:

  1. 制作一个大小为n数组(其中 n 是节点数),并将其初始化为全 0。
  2. S开始深度优先搜索,并将T作为目的地。
  3. 将当前节点的值0更改为1,在visited数组中,以跟踪该路径中访问的节点。
  4. 如果无法达到T ,那么它们之间就不可能存在简单的循环。所以,打印号。
  5. 如果达到T 则将目的地更改为S并继续深度优先搜索。现在,除了S之外,已经访问过的节点不能再次访问。
  6. 如果达到S ,则打印Yes,否则打印No。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to create graph
void createGraph(vector >& graph,
                 vector >& edges)
{
    for (auto x : edges) {
 
        // As it is an undirected graph
        // so add an edge for both directions
        graph[x[0]].push_back(x[1]);
        graph[x[1]].push_back(x[0]);
    }
}
 
bool findSimpleCycle(int cur,
                     vector >& graph,
                     int start, int dest,
                     vector& visited,
                     bool flag)
{
 
    // After reaching T, change the dest to S
    if (!flag and cur == dest) {
        dest = start;
        flag = 1;
    }
 
    // If S is reached without touching a
    // node twice except S and T,
    // then return true
    if (flag and cur == dest) {
        return true;
    }
 
    bool ans = 0;
    visited[cur] = 1;
    for (auto child : graph[cur]) {
 
        // A node can only be visited if it
        // hasn't been visited or if it
        // is S or t
        if (!visited[child] or child == dest) {
            ans = ans
                  | findSimpleCycle(
                        child, graph, start,
                        dest, visited, flag);
        }
    }
 
    // Change visited of the current node
    // to 0 while backtracking again so
    // that all the paths can be traversed
    visited[cur] = 0;
 
    return ans;
}
 
int main()
{
    int nodes = 7;
    vector > edges
        = { { 0, 1 }, { 1, 2 }, { 2, 3 },
            { 3, 4 }, { 4, 5 }, { 5, 2 },
            { 2, 6 }, { 6, 0 } };
    int S = 0, T = 4;
 
    // To store the graph
    vector > graph(nodes);
 
    // To keep track of visited nodes
    vector visited(nodes);
    createGraph(graph, edges);
 
    // If there exists a simple
    // cycle between S & T
    if (findSimpleCycle(S, graph,
                        S, T, visited, 0)) {
        cout << "Yes";
    }
 
    // If no simple cycle exists
    // between S & T
    else {
        cout << "No";
    }
}


Python3
# Function to create graph
def createGraph(edges, N):
    graph = list([] for _ in range(N))
    for node1, node2 in edges:
 
        # As it is an undirected graph,
        # add an edge for both directions
        graph[node1].append(node2)
        graph[node2].append(node1)
 
    return graph
 
 
def findSimpleCycle(cur,
                    graph,
                    start,  dest,
                    visited,
                    flag):
 
    # After reaching T, change the dest to S
    if ((not flag) and cur == dest):
        dest = start
        flag = True
 
    # If S is reached without touching a
    # node twice except S and T,
    # then return true
    if (not flag and cur == dest):
        return True
 
    # first guess is that there is no cycle
    # so ans is False.
    # if we find one cycle, ans will be true
    # and then returned .
    ans = False
 
    # mark node as visited in this path
    visited[cur] = True
 
    for child in graph[cur]:
 
        # A node can only be visited if it
        # hasn't been visited or if it
        # is S or t
        if (not visited[child]) or child == dest:
            ans = ans or findSimpleCycle(
                child, graph, start,
                dest, visited, flag)
 
    # Change visited of the current node
    # to 0 while backtracking again so
    # that all the paths can be traversed
    visited[cur] = False
 
    return ans
 
 
if __name__ == "__main__":
 
    N = 7  # number of nodes
    edges = [[0, 1], [1, 2], [2, 3],
             [3, 4], [4, 5], [5, 2],
             [2, 6], [6, 0]]
    S = 0
    T = 4
 
    # To keep track of visited nodes
    visited_array = list(False for _ in range(N))
 
    # If there exists a simple
    # cycle between S & T
    if (findSimpleCycle(cur=S, graph=createGraph(edges, N),
                        start=S, dest=T,
                        visited=visited_array,
                        flag=0)):
        print("Yes")
 
    # If no simple cycle exists
    # between S & T
    else:
        print("No")


Javascript


输出
No

时间复杂度: O(N!)。正如我们在这个算法中看到的,所有路径都可以遍历,在最坏的情况下,我们将遍历所有路径以找到有效的路径,请参阅这篇文章:https://www.geeksforgeeks.org/count-possible-路径-两个-顶点/
辅助空间: O(N^2)