import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
class Edge implements Comparable<Edge> {
int startVertex, endVertex, weight;
@Override
public int compareTo(Edge otherEdge) {
if (weight < otherEdge.weight)
return -1;
else if (weight == otherEdge.weight)
return 0;
else
return 1;
}
}
public class KruskalAlgorithm {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int vertexNum;
int countEdge;
int totalEdge;
List<Edge> allEdgeList = new ArrayList<Edge>();
Map<Integer, Map<Integer, Integer>> minSpanTree = new HashMap<Integer, Map<Integer, Integer>>();
try {
System.out.print("please input the number of total vertexes:");
vertexNum = sc.nextInt();
System.out.println("please input the graph:");
for (int i=1; i<=vertexNum; i++) {
for (int j=1; j<=vertexNum; j++) {
String theWeight = sc.next();
if (!theWeight.equals("i") && i < j) {
Edge theEdge = new Edge();
theEdge.startVertex = i;
theEdge.endVertex = j;
theEdge.weight = Integer.parseInt(theWeight);
allEdgeList.add(theEdge);
}
}
}
} finally {
sc.close();
}
for (int i=1; i<=vertexNum; i++) {
minSpanTree.put(i, new HashMap<Integer, Integer>());
for (int j=1; j<=vertexNum; j++)
minSpanTree.get(i).put(j, Integer.MAX_VALUE);
}
Collections.sort(allEdgeList);
countEdge = 0;
totalEdge = vertexNum - 1;
while (countEdge != totalEdge) {
Edge smallestEdge = allEdgeList.remove(0);
if (!checkCycle(minSpanTree, vertexNum, smallestEdge.startVertex, smallestEdge.startVertex, smallestEdge.endVertex)) {
minSpanTree.get(smallestEdge.startVertex).put(smallestEdge.endVertex, smallestEdge.weight);
minSpanTree.get(smallestEdge.endVertex).put(smallestEdge.startVertex, smallestEdge.weight);
countEdge++;
}
}
System.out.println("the minimal spanning tree:");
for (int i=1; i<=vertexNum; i++) {
for (int j=1; j<=vertexNum; j++) {
if (minSpanTree.get(i).get(j) == Integer.MAX_VALUE)
System.out.printf("%3s", "i");
else
System.out.printf("%3d", minSpanTree.get(i).get(j));
}
System.out.println();
}
}
private static boolean checkCycle(Map<Integer, Map<Integer, Integer>> minSpanTree, int vertexNum, int originalVertex, int preVertex, int nowVertex) {
if (originalVertex == nowVertex)
return true;
else {
for (int i=1; i<=vertexNum; i++) {
if (minSpanTree.get(nowVertex).get(i) != Integer.MAX_VALUE && i != preVertex && checkCycle(minSpanTree, vertexNum, originalVertex, nowVertex, i))
return true;
}
return false;
}
}
}
範例輸入輸出:
抱歉沒空說明程式碼,只能說明一下輸入輸出的部份。首先輸入圖形上總共點的數量,再輸入相鄰矩陣,橫軸表示點1~點10,縱軸也是表示點1~點10,輸入的是點到點之間的權重,若輸入i表示這兩點不相連,也就是權重無限大。輸出結果也是相鄰矩陣,表示找到的最小成本擴展樹。本範例輸入是採用課本習題2的圖,所以可以參照課本的圖方便了解。

沒有留言:
張貼留言