我们有一个加权图,我们想要制作一个具有以下条件的最佳树:
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的树
答案 0 :(得分:1)
您可以将Dijkstra's algorithm与U
一起用作起始节点。它将为您提供距U
的所有顶点的最短距离。如果仅考虑用于计算到所有顶点的最短距离的那些边,则将获得所需的树。
现在要获得所有边缘,您需要在算法中进行一些修改。您需要维护一个父数组,该数组保存有关当前顶点所依赖的顶点的信息(计算最短距离时)。
例如,我们有两个顶点U
和V
,距离某些源S
的所有顶点的距离都存储在distance[]
数组中。
现在假设我们在E
和U
之间有一个边V
,其中权重W
和条件distance[U] > distance[V] + W
得到满足,然后parent
U
1}}将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