我怎样才能制作出一些条件最优的树

时间:2018-04-05 18:24:57

标签: 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个带树的数字。例如(2 3 50)表示顶点2与顶点3连接,重量为50。

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

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

1 个答案:

答案 0 :(得分:1)

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

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

例如,我们有两个顶点UV,距离某些源S的所有顶点的距离都存储在distance[]数组中。 现在假设我们在EU之间有一个边V,其中权重W和条件distance[U] > distance[V] + W得到满足,然后parent U 1}}将Vdistance[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