克鲁斯克尔算法Kruskal‘s algorithm java code
参考了 https://zh.wikipedia.org/wiki/%E5%85%8B%E9%B2%81%E6%96%AF%E5%85%8B%E5%B0%94%E6%BC%94%E7%AE%97%E6%B3%95
因为没有给出java版的代码,所以自己写了:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.StringTokenizer;
//5 7
//1 2 9
//1 5 5
//2 5 3
//2 3 8
//2 4 2
//3 4 9
//4 5 6
//6 9
//1 2 8
//1 4 9
//2 4 1
//2 5 5
//2 3 6
//2 6 2
//3 6 7
//4 5 3
//5 6 4
class Comp4 implements Comparator<Edgee> {
@Override
public int compare(Edgee o1, Edgee o2) {
// return o2.weight-o1.weight;//max
return o1.weight - o2.weight;// mini
}
}
class Vertev {
int key;
public Vertev(int key) {
this.key = key;
}
}
class Edgee {
Vertev from;
Vertev to;
int weight;
public Edgee(Vertev from, Vertev to, int weight) {
this.from = from;
this.to = to;
this.weight = weight;
}
}
public class kruskal {
public static void main(String[] args) throws IOException {
kruskalGraph();
doMethod();
}
static int vs, es;
public static List<Set<Edgee>> Graph = new ArrayList<>();
public static List<Set<Vertev>> AGraph = new ArrayList<>();
public static PriorityQueue<Edgee> pq = new PriorityQueue<Edgee>(new Comp4());
public static void kruskalGraph() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
vs = Integer.parseInt(st.nextToken());
es = Integer.parseInt(st.nextToken());
for (int s = 0; s < es; s++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
Vertev vx = new Vertev(x);
Vertev vy = new Vertev(y);
Edgee edg = new Edgee(vx, vy, w);
pq.add(edg);
}
}
public static void doMethod() {
while (!pq.isEmpty()) {
Edgee edge = pq.poll();
checkConn(edge);
if (Graph.size() >= 2) {
joinone();
}
}
Iterator it = Graph.get(0).iterator();
int Sum = 0;
while (it.hasNext()) {
Edgee v = (Edgee) it.next();
System.out.println(" from " + v.from.key + "---> to " + v.to.key + " weight " + v.weight);
Sum += v.weight;
}
System.out.println(Sum);
}
public static void joinone() {
Set<Edgee> newGraph = Graph.get(0);
Set<Vertev> newSet = AGraph.get(0);
ArrayList<Integer> keep = new ArrayList<>();
for (int g = 1; g < AGraph.size(); g++) {
Iterator it = AGraph.get(g).iterator();
int mark = 0;
while (it.hasNext()) {
Vertev h = (Vertev) it.next();
if (isSetContain(newSet, h)) {// -- 包涵两个以上的不能加 排除
mark++;
if (mark >= 2) {
break;
}
}
}
if (mark < 2) {
newGraph.addAll(Graph.get(g));
Graph.remove(g);
keep.add(g);
} else {
Graph.remove(g);
keep.add(g);
}
}
for (int i = 0; i < keep.size(); i++) {
AGraph.remove(i);
}
}
public static void checkConn(Edgee edge) {
boolean ishas = false;
AGraph = new ArrayList<>();
for (Set<Edgee> st : Graph) {
Set<Vertev> aset = new HashSet<Vertev>();
Iterator it = st.iterator();
while (it.hasNext()) {
Edgee e = (Edgee) it.next();
aset.add(e.from);
aset.add(e.to);
}
if (isSetContain(aset, edge.from) && !isSetContain(aset, edge.to)) {
st.add(edge);
aset.add(edge.to);
ishas = true;
} else if (!isSetContain(aset, edge.from) && isSetContain(aset, edge.to)) {
st.add(edge);
aset.add(edge.from);
ishas = true;
}
AGraph.add(aset);
}
if (!ishas) {
if (Graph.size() == 0) {
Set<Vertev> aset = new HashSet<Vertev>();
aset.add(edge.from);
aset.add(edge.to);
AGraph.add(aset);
}
Set<Edgee> tmp = new HashSet<>();
tmp.add(edge);
Graph.add(tmp);
}
}
public static boolean isSetContain(Set<Vertev> p, Vertev x) {
boolean ret = false;
Iterator it = p.iterator();
while (it.hasNext()) {
Vertev t = (Vertev) it.next();
if (t.key == x.key) {
ret = true;
break;
}
}
return ret;
}
}