城市建设__最小生成树(Kruscal)

 分析:

  • 构造最小生成树的时候需要用到道路的排序,所以对起始节点终止节点和道路花费进行封装,然后对边进行归并
  • 然后依次归并最小花费价值的道路对应的节点
  • 一条道路上当两个节点都被归并的时候不可以再次归并
/**
*@author yangyvting
*@date 2019年5月5日
*/
package 图论;

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static int n , m; //城市的个数和对应的道路数目
	 
	public static boolean vis[];
	public static int riverWay[];
	public static Edge edgeWay[];
	public static int min = 0;
	public static int t = 0;
	
	public static void main(String[] args) {
		Scanner sca = new Scanner(System.in);
		n = sca.nextInt();
        m = sca.nextInt();
        
        vis = new boolean[n + 1];
        riverWay = new int[n + 1];
        edgeWay = new Edge[n + m];
        
        //输入道路
        for(int i = 0; i < m; i ++) {
        	int x = sca.nextInt();
        	int y = sca.nextInt();
        	int z = sca.nextInt();
        	edgeWay[t ++] = new Edge(x, y, z); 
        }
        //输入码头 //将码头算到图中
        for(int i = 0; i < n; i ++) {
        	riverWay[i + 1] = sca.nextInt();
        	 
        	edgeWay[t ++] = new Edge(0, i + 1, riverWay[i + 1]); 
        	 
        }      
        
        //生成最小生成树
        Kruscal();
        
        //最小花费
        System.out.println("最小花费为:");
        System.out.println(min);
	}

	private static void Kruscal() {
		Arrays.sort(edgeWay);
		
		System.out.println("道路消费从小到大排序为:");
		for(int i = 0; i < 2 * n; i ++) {
			System.out.println(edgeWay[i].toString());
		}
		for(int i = 0; i < 2 * n; i ++) {
			if( edgeWay[i].weight < 0) continue;
			if(!vis[edgeWay[i].start] || !vis[edgeWay[i].end] ) {
				min += edgeWay[i].weight;
				vis[edgeWay[i].start] = vis[edgeWay[i].end] = true;
			}
		}
	}
}
class Edge implements Comparable<Edge>{
	int start;
	int end;
	int weight;
	Edge(int start, int end, int weight ){
		this.start = start;
		this.end = end;
		this.weight = weight;
	}
	@Override
	public int compareTo(Edge o) {
		
		return this.weight - o.weight;
	}
	public String toString() {
		String st = new String();
		st = this.start + " " + this.end + " " + this.weight;
		return st;
	}
}
 

运行结果
 

5 5
1 2 4
1 3 -1
2 3 3
2 4 5
4 5 10
-1 10 10 1 1
道路消费从小到大排序为:
1 3 -1
0 1 -1
0 4 1
0 5 1
2 3 3
1 2 4
2 4 5
4 5 10
0 2 10
0 3 10
最小花费为:
9

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值