Java计算一个带权的图上最短的边和最长的边

Java计算一个带权的图上最短的边和最长的边,并且判断是否有回路,这里三个输出必须用3个循环么?能不能只用一个循环的呢

效果图

img


代码如下:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Graph {
    private int V;
    private List<List<Edge>> adj;
    private boolean hasCycle = false;

    private static class Edge {
        int to;
        int weight;

        public Edge(int to, int weight) {
            this.to = to;
            this.weight = weight;
        }
    }

    public Graph(int V) {
        this.V = V;
        adj = new ArrayList<>(V);
        for (int i = 0; i < V; i++) {
            adj.add(new ArrayList<>());
        }
    }

    public void addEdge(int from, int to, int weight) {
        adj.get(from).add(new Edge(to, weight));
    }

    public void shortestAndLongestEdges() {
        int shortest = Integer.MAX_VALUE;
        int longest = Integer.MIN_VALUE;

        boolean[] visited = new boolean[V];
        for (int i = 0; i < V; i++) {
            if (!visited[i]) {
                int[] distances = {0, 0};

                dfs(i, visited, distances, new HashSet<>());

                if (distances[0] < shortest) {
                    shortest = distances[0];
                }
                if (distances[1] > longest) {
                    longest = distances[1];
                }
            }
        }

        System.out.println("最短边: " + shortest);
        System.out.println("最长边: " + longest);
        System.out.println("是否存在回路: " + hasCycle);
    }

    private void dfs(int u, boolean[] visited, int[] distances, Set<Integer> path) {
        visited[u] = true;
        path.add(u);

        for (Edge edge : adj.get(u)) {
            if (!visited[edge.to]) {
                distances[0] += edge.weight;
                distances[1] += edge.weight;

                dfs(edge.to, visited, distances, path);

                distances[1] -= edge.weight;
            } else if (path.contains(edge.to)) {
                distances[1] += edge.weight;
                hasCycle = true;
            }
        }

        path.remove(u);
    }

    public static void main(String[] args) {
        Graph graph = new Graph(6);
        graph.addEdge(0, 1, 5);
        graph.addEdge(1, 2, 3);
        graph.addEdge(2, 3, 6);
        graph.addEdge(2, 4, 8);
        graph.addEdge(4, 5, 2);
        graph.addEdge(5, 3, 7);

        graph.shortestAndLongestEdges();
    }
}


该回答引用ChatGPT-3.5,仅供参考,不保证完全正确

可以使用一个循环来计算一个带权图上的最短边、最长边以及检测是否存在回路。以下是使用单个循环实现的示例代码:

import java.util.ArrayList;
import java.util.List;

class WeightedEdge {
    int source;
    int destination;
    int weight;

    public WeightedEdge(int source, int destination, int weight) {
        this.source = source;
        this.destination = destination;
        this.weight = weight;
    }
}

class Graph {
    int vertices;
    List<WeightedEdge> edges;

    public Graph(int vertices) {
        this.vertices = vertices;
        edges = new ArrayList<>();
    }

    public void addEdge(int source, int destination, int weight) {
        WeightedEdge edge = new WeightedEdge(source, destination, weight);
        edges.add(edge);
    }

    public void findShortestAndLongestEdges() {
        int shortest = Integer.MAX_VALUE;
        int longest = Integer.MIN_VALUE;

        for (WeightedEdge edge : edges) {
            if (edge.weight < shortest) {
                shortest = edge.weight;
            }

            if (edge.weight > longest) {
                longest = edge.weight;
            }
        }

        System.out.println("Shortest edge: " + shortest);
        System.out.println("Longest edge: " + longest);
    }

    public boolean hasCycle() {
        int[] parent = new int[vertices];
        for (int i = 0; i < vertices; i++) {
            parent[i] = i;
        }

        for (WeightedEdge edge : edges) {
            int sourceParent = findParent(parent, edge.source);
            int destinationParent = findParent(parent, edge.destination);

            if (sourceParent == destinationParent) {
                return true; // Cycle detected
            }

            parent[sourceParent] = destinationParent;
        }

        return false; // No cycle
    }

    private int findParent(int[] parent, int vertex) {
        if (parent[vertex] != vertex) {
            parent[vertex] = findParent(parent, parent[vertex]);
        }
        return parent[vertex];
    }
}

public class Main {
    public static void main(String[] args) {
        // Create a graph
        int vertices = 5;
        Graph graph = new Graph(vertices);

        // Add weighted edges
        graph.addEdge(0, 1, 5);
        graph.addEdge(1, 2, 9);
        graph.addEdge(2, 3, 3);
        graph.addEdge(3, 4, 7);
        graph.addEdge(4, 0, 2);

        // Find shortest and longest edges
        graph.findShortestAndLongestEdges();

        // Check if there is a cycle
        if (graph.hasCycle()) {
            System.out.println("The graph contains a cycle.");
        } else {
            System.out.println("The graph does not contain a cycle.");
        }
    }
}

这个示例代码中,Graph 类表示带权图,WeightedEdge 类表示带权边。findShortestAndLongestEdges 方法在单个循环中计算最短边和最长边的权重值。hasCycle 方法使用并查集算法来检测图中是否存在回路。注意,在上述代码中,我假设图中的顶点编号从0开始,你可以根据需要进行调整。


该回答引用NewBing,仅供参考,不保证完全正确

根据我从网络上搜索到的信息,有以下几种方法可以实现这个功能:

  • 一种方法是使用Dijkstra算法,它是一种求解单源最短路径的算法,可以找到从一个顶点到其他所有顶点的最短路径。然后,你可以遍历所有的边,找到最短的边和最长的边,并且检查是否有回路。这种方法的时间复杂度是O(V^2+E),其中V是顶点数,E是边数。你可以参考这篇文章这篇文章来了解更多关于Dijkstra算法的细节和实现。
  • 另一种方法是使用Floyd算法,它是一种求解多源最短路径的算法,可以找到任意两个顶点之间的最短路径。然后,你也可以遍历所有的边,找到最短的边和最长的边,并且检查是否有回路。这种方法的时间复杂度是O(V^3),其中V是顶点数。你可以参考这篇文章来了解更多关于Floyd算法的细节和实现。
  • 还有一种方法是使用Bellman-Ford算法或SPFA算法,它们也是求解单源最短路径的算法,但是可以处理存在负权边的情况。然后,你同样可以遍历所有的边,找到最短的边和最长的边,并且检查是否有回路。这种方法的时间复杂度是O(VE),其中V是顶点数,E是边数。你可以参考这篇文章来了解更多关于Bellman-Ford算法和SPFA算法的细节和实现。

源: 与必应的对话, 2023/7/18
(1) Java数据结构与算法笔记——带权图最短路径(Dijkstra算法)_Mr. Wanderer的博客-CSDN博客. https://blog.csdn.net/Mr_Wanderer/article/details/114241243.
(2) 最短路算法(Dijkstra + SPFA + Floyd) - 知乎 - 知乎专栏. https://zhuanlan.zhihu.com/p/357580063.
(3) 最短路算法(Dijkstra + SPFA + Floyd) - 知乎 - 知乎专栏. https://zhuanlan.zhihu.com/p/357580063.
(4) 最短路算法(Dijkstra + SPFA + Floyd) - 知乎 - 知乎专栏. https://zhuanlan.zhihu.com/p/357580063.
(5) 【Java】最短路径--Dijkstra_输入若干个字符对和一个整数,分别表示弧尾、弧头和权值,以#作为输入结束_Alkaid:的博客-CSDN博客. https://blog.csdn.net/weixin_45867159/article/details/112546417.

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/238964
  • 这篇博客你也可以参考下:编写一个java类,用来表示出部队中 军 师 旅 团这种树状数据结构,使上级能检索到下级,下级也能检索到上级
  • 除此之外, 这篇博客: java初级程序员必备的算法和数据结构入门只是,编程界的敲门砖,算法合集,简单详细中的 如何判断是否为排序好的数组 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 在第一个数组内部,定义一个布尔类型的变量,如果在进入循环的时候,把结构设置为true,也就是第一次排序后,没有任何移动的话,那么数组布尔就不会变成false

    在这里插入图片描述

  • 您还可以看一下 徐无忌老师的Java进阶高手课-深入浅出Java网络编程课程中的 案例实战:浏览器打开一个网址,整个过程是怎么样的?小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    根据问题描述和参考代码,可以看出这个问题是关于计算带有权重的图上的最短边和最长边,并判断是否存在回路。通过分析代码,目前有三个循环来实现这三个输出,但是没有提供图的数据结构和权重计算的具体算法。

    在没有图的数据结构和权重计算算法的情况下,无法直接给出具体的解决方案来计算最短边和最长边。但是可以给出一些思路来实现这些功能。

    第一步:定义图的数据结构 在Java中,可以使用邻接矩阵或邻接表来表示图的数据结构。邻接矩阵是一个二维矩阵,矩阵的行和列分别表示图中的顶点,矩阵中的值表示边的权重。邻接表是一个链表数组,数组的每个元素对应一个顶点,链表中存储与该顶点相邻的顶点及对应的边的权重。

    第二步:实现最短边的计算 最短边的计算可以使用Dijkstra算法或Floyd-Warshall算法。Dijkstra算法是一种单源最短路径算法,可以计算从一个顶点到其他所有顶点的最短路径。Floyd-Warshall算法是一种多源最短路径算法,可以计算任意两个顶点之间的最短路径。通过这些算法,可以找到图中的最短边并输出。

    第三步:实现最长边的计算 最长边的计算可以直接找到图中边权重的最大值即可。遍历图的所有边,比较边的权重,找到最大值并输出。

    第四步:判断是否存在回路 判断图中是否存在回路可以使用深度优先搜索或广度优先搜索。通过深度优先搜索或广度优先搜索遍历图的顶点,如果遍历到已经访问过的顶点,则说明存在回路。可以使用一个标记数组来记录顶点的访问情况。

    根据以上思路,可以给出相应的代码实现。但是还需要具体的图数据结构和权重计算算法的支持才能完成整个问题的解决。根据目前提供的参考代码和问题描述,无法得知具体的图数据结构和权重计算算法,无法给出具体的解决方案。