深度优先搜索和图表中的最长路径

时间:2015-03-05 19:40:15

标签: java recursion graph depth-first-search

我正在研究一个问题,你必须在图中找到最长的路径。该图是唯一的,因为它是定向的(流量只有一种方式),您可以从一个节点移动到图中的另一个节点。我使用深度优先搜索算法编写了一些代码来找到答案。我的算法为某些图表提供了正确的答案,为其他图表提供了错误的答案。这也比我想要的时间更长。

这是代码。

import java.util.ArrayList;
import java.util.Scanner;

public class Martians { // 12442

    static int max = 0; // longest chain length
    static int tMax = 0; // longest current chain
    static int starter = 0; // starting Martian of longest length
    static int tStarter = 0;
    static boolean[] visited;
    static boolean[] tVisited;
    static ArrayList<Edge>[] graph;

    static class Edge {
        public int dest = -1; // destination

        public Edge() {
        }

        public Edge(int v) {
            dest = v;
        }
    }

    public static void dfs(int start) { // RECURSIVEEEEE!!!!
        tVisited[start] = true;
        visited[start] = true;
        tMax++;
        if (tMax > max) {
            max = tMax;
            starter = tStarter;
        } 
        else if (tMax == max && tStarter < starter) {
            max = tMax;
            starter = tStarter;
        }

        ArrayList<Edge> edges = graph[start];

        for (Edge e : edges) {
            if (!tVisited[e.dest] && !visited[e.dest]) {// propagates out into graph if the current
                                    // // node has not been visited
                dfs(e.dest);
            }
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int r = in.nextInt();
        for (int q = 1; q <= r; ++q) {
            tMax = 0;
            tStarter = 0;
            int N = in.nextInt();
            graph = new ArrayList[N + 1];
            visited = new boolean[N + 1];
            tVisited = new boolean[N + 1];
            for (int i = 1; i <= N; ++i) {
                graph[i] = new ArrayList<Edge>();
                visited[i] = false;
                tVisited[i] = false;
            }

            for (int i = 1; i <= N; ++i) {
                int u = in.nextInt();
                int v = in.nextInt();
                graph[u].add(new Edge(v));
            }

            for (int i = 1; i <= N; ++i) {
                if (!visited[i]) {
                    tStarter = i;
                    dfs(i);
                }
            }

            System.out.println("Case " + q + ": " + starter);
        }
        in.close();
    }

}

输入看起来像这样:

3
3
1 2
2 3
3 1
4
1 2
2 1
4 3
3 2
5
1 2
2 1
5 3
3 4
4 5

第一个整数是图表的数量。之后,每个单独的整数是节点数,成对的整数分别是节点和节点。输出是一个应该开始的节点,以便在图形中移动最长距离而不会多次访问任何节点(没有重复)。

输出:

Case 1: 1
Case 2: 4
Case 3: 3

有人对我在这里做错了什么有任何建议吗?

1 个答案:

答案 0 :(得分:0)

如果某些图表的值不正确,而其他图表的值不正确,则问题可能与您如何跟踪已访问过的节点有关。

我有2条建议:

  1. 为变量提供更具描述性的名称。 tVisited在功能上等同于visited,使您的代码阅读更加困难。

  2. 创建一个非常非常简单的图形并添加检测以打印出访问过的节点,以便您可以跟踪算法的行为,以确保它与您期望的一致。

    < / LI>