参考了https://zh.wikipedia.org/wiki/%E6%99%AE%E6%9E%97%E5%A7%86%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.Iterator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
class Comp3 implements Comparator<Edge>{
@Override
public int compare(Edge o1, Edge o2) {
return o2.key-o1.key;//max
//return o1.key-o2.key;//mini
}
}
public class Prim {
public static List<Vertex> vertexList = new ArrayList<Vertex>();//结点集
public static List<Edge> EdgeQueue = new ArrayList<Edge>();//边集
public static List<Vertex> VisitedVertex = new ArrayList<Vertex>();//已经 访问过的结点
public static List<Edge> VisitedEdge = new ArrayList<Edge>();//已经 访问过的边
public static void main(String[] args) throws IOException {
primTree();
}
// 5 7
// 1 2 9
// 1 5 5
// 2 5 3
// 2 3 8
// 2 4 2
// 3 4 9
// 4 5 6
// result:
// from 1---> to 5 weight 5
// from 2---> to 5 weight 3
// from 2---> to 4 weight 2
// from 2---> to 3 weight 8
// 18
static int vs,es;
public static void buildGraph() 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());
Vertex vx = new Vertex(x+"");
if(!Prim.containVertex2(vx)){
Prim.vertexList.add(vx);
}
Vertex vy = new Vertex(y+"");
if(!Prim.containVertex2(vy)){
Prim.vertexList.add(vy);
}
addEdge(vx, vy, w);
}
}
public static void addEdge(Vertex a, Vertex b, int w) {
Edge e = new Edge(a, b, w);
Prim.EdgeQueue.add(e);
}
public static void primTree() throws IOException {
buildGraph();
Vertex current = vertexList.get(0);
VisitedVertex.add(current);
Edge ex=findMinEdge();
while(Prim.VisitedVertex.size()<vs){
if(ex!=null){
if(!isVisted(ex.end)){
current=ex.end;
}
else if(!isVisted(ex.start)){
current=ex.start;
}
VisitedVertex.add(current);
VisitedEdge.add(ex);
ex=findMinEdge();
}
}
Iterator it = VisitedEdge.iterator();
int Sum=0;
while (it.hasNext()) {
Edge v = (Edge) it.next();
System.out.println(" from "+v.start.key+"---> to "+v.end.key+" weight "+v.key);
Sum+=v.key;
}
System.out.println(Sum);
}
public static boolean isVisted(Vertex ex){
boolean iRp=false;
for(Vertex vt:Prim.VisitedVertex){
if(vt.key.equals(ex.key)){
iRp=true;
break;
}
}
return iRp;
}
public static boolean isRepeat(Edge ex){
boolean iRp=false;
for(int i=0;i<VisitedEdge.size();i++){
if((VisitedEdge.get(i).start.key.equals(ex.start.key)&&VisitedEdge.get(i).end.key.equals(ex.end.key))
||(VisitedEdge.get(i).start.key.equals(ex.end.key)&&VisitedEdge.get(i).end.key.equals(ex.start.key))){
iRp=true;
}
}
return iRp;
}
public static Edge findMinEdge(){
PriorityQueue<Edge> pq=new PriorityQueue<Edge>(new Comp3());
for(Vertex vv:VisitedVertex){
for(Edge e:EdgeQueue){
if(e.start.key.equals(vv.key)||e.end.key.equals(vv.key)){
boolean isAreadhas=false;
isAreadhas=isRepeat(e);
if(!isAreadhas){
if(!(isVisted(e.start)&&isVisted(e.end))){
pq.add(e);
}
}
}
}
}
if(!pq.isEmpty()){
Edge tmp= pq.poll();
return tmp;
}else return null;
}
public static boolean containVertex(Vertex vte) {
for (Vertex v : VisitedVertex) {
if (v.key.equals(vte.key))
return true;
}
return false;
}
public static boolean containVertex2(Vertex vy) {
for (Vertex v : Prim.vertexList) {
if (v.key.equals(vy.key))
return true;
}
return false;
}
}
class Vertex {
String key;
Vertex(String key) {
this.key = key;
}
}
class Edge {
Vertex start;
Vertex end;
int key;
Edge(Vertex start, Vertex end, int key) {
this.start = start;
this.end = end;
this.key = key;
}
}