普里姆算法Prim‘s algorithm java code

参考了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;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值