图表访问每个节点一次并到达出口

时间:2014-03-12 20:39:26

标签: algorithm graph path depth-first-search

我现在有一个测试,这是其中一个问题:

输入

迷宫中的游览地点从1到n。入口和 出口分别对应于数字1和数字n;剩余的 数字对应于过境点。请注意,没有死角 连接一对交叉点的连接数不超过一个。 对于每个测试用例,第一行给出n和连接数 在交叉点之间(m)。然后,在以下m行中的每一行中,找到一对 对应于两个交叉点之间连接的整数。

输出

对于每个测试用例,您的实现应输出一行 包含"发现!",如果有可能通过访问每个到达出口 穿过一次或者#34;该死的!"否则。其他测试用例可能会随之而来。

约束

  • m< 32
  • n< 21

示例输入:

8 13
1 2
1 3
2 3    
2 4    
3 4    
3 5    
4 5    
4 6    
5 6    
5 7
6 7
6 8    
7 8    
8 8    
1 2    
1 3    
2 4    
3 5    
4 6    
5 7    
6 8    
7 8

示例输出:

Found!
Damn!

我使用一种DFS算法解决了这个问题,但我有几个问题。

使用DFS算法,我实现了一个递归函数,它在给定节点中启动并尝试访问每个节点一次,最后一个节点必须是退出节点。我现在没有完整的代码,但它是这样的:

findPath(int current node, int numVisitedNodes, int *visited){
    int *tmpVisited = copyArray(visited); //copies the visited array to tmpVisited

    //DFS algo here
}

每次递归调用都会复制访问过的节点数组。我这样做是因为当它找到无效路径并且递归返回到原点时,它仍然可以继续,因为没有人覆盖被访问节点列表。

有没有更好的方法呢?

你会如何解决? (如果需要,您可以提供代码)

2 个答案:

答案 0 :(得分:0)

  1. 阅读交叉点
  2. 如果过境的开始或结束属于可到达的集合,则将两者都添加到该集合中,否则创建新的可达集合。
  3. 输入完成后,检查是否有任何可到达的集合 入口和出口点
  4. HashSet操作复杂度为O(1)。如果每个交叉点都是不同的,则复杂度为O(n ^ 2),这是该算法的最坏情况复杂度。空间复杂度为O(n),没有递归,因此没有内存的递归开销。

    粗略地说,每个节点只访问一次。

    使用有效可达集的Java代码如下。

    public class ZeManel {
    
        public static void main(String[] args) {
            Integer[][] input = {{1,2},{2,3},{4,6}};
            zeManel(input);
        }
    
        public static void zeManel(Integer[][] input){
            List<Set<Integer>> paths = new ArrayList<Set<Integer>>();
            int max = 0;
            for(int i = 0;i < input.length;i++) {
                max = input[i][0] > max ? input[i][0] : max;
                max = input[i][1] > max ? input[i][1] : max; 
                boolean inPaths = false;
                for (Set<Integer> set : paths) {    
                    if(set.contains(input[i][0]) || set.contains(input[i][1])) {
                        set.add(input[i][0]);
                        set.add(input[i][1]);
                        inPaths = true;
                        break;
                    }
                }
                if(!inPaths) {
                    Set<Integer> path = new HashSet<Integer>();
                    path.add(input[i][0]);
                    path.add(input[i][1]);
                    paths.add(path);
                }
    
            }
            for (Set<Integer> path : paths) {
                if(path.contains(1) && path.contains(max)) {
                    System.out.println("Found!");
                    return;
                }
            }
            System.out.println("Damn!");
        }
    
    }
    

答案 1 :(得分:0)

这是我在测试期间的实施:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

# define N 21
# define M 32

int i;
int adj[N][N];
int count = 0;

int findPath(int numNodes, int currentNode, int depth, int *visited){

    visited[currentNode] = 1;

    if(currentNode == numNodes - 1 && depth == numNodes){
        return 1;
    }

    if(depth > numNodes)
        return -1;

    int r = -1;

    if(depth < numNodes){
        count++;
        int *tmp = (int*) malloc(numNodes*sizeof(int));
        for(i = 0; i < numNodes; i++)
            tmp[i] = visited[i];


        for(i = 0; i < numNodes; i++){

            if(adj[currentNode][i] == 1 && tmp[i] == 0 && r == -1){
                if(findPath(numNodes, i, depth + 1, tmp) == 1)
                    r = 1;
            }

        }

        free(tmp);
    }
    return r;
}

int main(){

    int numLigacoes, a, b, numNodes;
    int *visited;

    while (scanf("%d %d", &numNodes, &numLigacoes) != EOF){
        visited = (int*) malloc(numNodes*sizeof(int));
        count = 0;
        memset(adj, 0, N*N*sizeof(int));
        memset(visited, 0, numNodes*sizeof(int));

        for (i = 0; i < numLigacoes; i++){
            scanf("%d %d", &a, &b);
            adj[a - 1][b - 1] = 1;
            adj[b - 1][a - 1] = 1;
        }

        if(findPath(numNodes, 0, 1, visited) == 1)
            printf("Found! (%d)\n", count);
        else
            printf("Damn! (%d)\n", count);

        free(visited);
    }

    return 0;
    }

您怎么看?