algorithm - 我怎样才能制作出满足某些条件的最佳树

标签 algorithm graph tree minimum

我们有一个加权图,我们想根据以下条件制作一棵最优树:

1) 树应该包含图中的所有顶点

2) 所有的树边都应该在图中

3) 从顶点U开始,以最小路径到达任何其他顶点。

根据初始图和条件,我们想要制作一棵具有最小权重的树。

例如:

输入

6 8

1 2 30

1 3 20

2 3 50

4 2 100

2 5 40

3 5 10

3 6 50

5 6 60

4

输出: 230

解释: 我们有 6 个顶点和 8 条边。之后我们有 8 strip 有树编号的线。例如 (2 3 50) 表示顶点 2 与顶点 3 相连,权重为 50。

最后我们有一个数字显示起始顶点。

所以如果我们从顶点 4 开始并以最小路径到达所有其他顶点,我们可以得到一棵总权重为 230 的树

最佳答案

您可以使用 Dijkstra's algorithmU作为起始节点。它将为您提供从 U 到所有顶点的最短距离.如果你只考虑那些用于计算到所有顶点的最短距离的边,你将得到所需的树。

现在要获得所有边,您需要对算法进行一些修改。您需要维护一个父数组,该数组保留有关当前顶点所依赖的顶点的信息(同时计算最短距离)。

例如,我们有两个顶点UV和来自某个来源的所有顶点的距离S存储在 distance[]大批。 现在假设我们有一条边 EU之间和 V有重量W和条件 distance[U] > distance[V] + W得到满足,然后 parentU将是 V作为distance[U]现在取决于 distance[V] .

因此我们将在更新 distance 的算法中再添加一步.最初 parent[source]将是 source本身,因为它不依赖于任何其他顶点。

最后,要获得所有边,您需要遍历 parent排列并打印 index <-> parent[index] .

Java 示例代码:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class ModifiedDijkstra {
    public static final long INF = (long) 1e15;

    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int totalVertices = sc.nextInt();
        int totalEdges = sc.nextInt();

        ArrayList<Edge> adjacencyList[] = new ArrayList[totalVertices + 1];

        for (int i = 1; i <= totalVertices; i++)
            adjacencyList[i] = new ArrayList<>();

        for (int i = 0; i < totalEdges; i++) {
            int u = sc.nextInt();
            int v = sc.nextInt();
            long weight = sc.nextInt();

            adjacencyList[u].add(new Edge(v, weight));
            adjacencyList[v].add(new Edge(u, weight));
        }

        int source = sc.nextInt();   //Source Index
        long distance[] = new long[totalVertices + 1];
        long edgesWeights[] = new long[totalVertices + 1];
        Arrays.fill(distance, INF);

        int parent[] = new int[totalVertices + 1];
        distance[source] = 0;
        parent[source] = source;

        Queue<Integer> queue = new LinkedList<>();
        queue.add(source);

        while (!queue.isEmpty()) {
            int currVertex = queue.poll();

            for (Edge edge : adjacencyList[currVertex]) {
                if (distance[edge.endVertex] > distance[currVertex] + edge.weight) {
                    distance[edge.endVertex] = distance[currVertex] + edge.weight;
                    parent[edge.endVertex] = currVertex;
                    edgesWeights[edge.endVertex] = edge.weight;
                    queue.add(edge.endVertex);
                }
            }
        }

        System.out.println("TREE : ");

        long edgesSum = 0;

        for (int i = 1; i <= totalVertices; i++) {
            if (parent[i] == i) //source
                continue;

            //Vertex1 <-> Vertex2 : Weight
            System.out.println(i + " <-> " + parent[i] + " : " + edgesWeights[i]);
            edgesSum += edgesWeights[i];
        }

        System.out.println("Sum of the weights of all edges is : " + edgesSum);


    }
}

class Edge {
    int endVertex;
    long weight;

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

输入:

6 8

1 2 30

1 3 20

2 3 50

4 2 100

2 5 40

3 5 10

3 6 50

5 6 60

4

输出:

TREE : 
1 <-> 2 : 30
2 <-> 4 : 100
3 <-> 2 : 50
5 <-> 2 : 40
6 <-> 3 : 50
Sum of the weights of all edges is : 270

关于algorithm - 我怎样才能制作出满足某些条件的最佳树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49679065/

相关文章:

algorithm - 方案中的后序遍历

ruby - ruby 中的树和图数据结构

c++ - 与 ctors 类 union 的替代方案

javascript - 为什么 Array.isArray 算法是 ES5 执行类型检查?

javascript - 滚动时根据线性渐变背景设置适当的元素颜色

python - 对于以下情况,NetworkX 的minimum_cut 算法是否正确?

excel - 是否可以使用 Graph Rest Api 删除 Excel 表中的所有行?

java - 有限重复置换算法

python - 在Python中实现中值选择算法的中值

python - 阅读 igraph 中的 Disconected Graph for python