NYOJ--38(图论)-题目--------------------------------布线问题

本文介绍了一种使用普里姆算法求解最小生成树的方法,通过实例演示了如何从输入数据中构建图并计算最小生成树的总费用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package org.acm.graph;

/*http://acm.nyist.net/JudgeOnline/problem.php?pid=38*/

//这是一道求最小生成树的题,用普里姆来做。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Scanner;

public class Graph_38 {

	private static int v, e;
	private static int lowcost[] = new int[505];// 临时数组
	private static int adjvex[] = new int[505];// 存放相关顶点的下标的
	private static int map[][] = new int[505][505];// 楼与楼之间拉线的费用
	private static int minsum, min, sum, max = Integer.MAX_VALUE;

	public static void main(String[] args) {

		Scanner sc = new Scanner(new BufferedReader(new InputStreamReader(System.in)));

		int n = sc.nextInt();
		while (n-- > 0) {

			v = sc.nextInt();
			e = sc.nextInt();

			min = max;// 哪个与总局相连
			minsum = 0;// 临时记录lowcost里最小的那个值
			sum = 0;// 结果
			Arrays.fill(adjvex, 1);// 初始化

			// 初始化
			for (int i = 1; i <= v; i++)
				for (int j = 1; j <= v; j++)
					if (i != j)
						map[i][j] = max;

			int a, b, c, d, k;
			for (int i = 0; i < e; i++) {
				a = sc.nextInt();
				b = sc.nextInt();
				c = sc.nextInt();
				map[a][b] = c;
				map[b][a] = c;
			}

			for (int i = 0; i < v; i++) {
				d = sc.nextInt();
				if (min > d)
					min = d;
			}

			// 先获取所有楼与1楼的费用,存到lowcost临时数组里
			for (int i = 1; i <= v; i++)
				lowcost[i] = map[1][i];

			for (int i = 1; i <= v; i++) {

				minsum = max;
				k = 1;
				// 在lowcost里获取最小的值,并记录下标存到adjvex里,这里就找到了哪个楼与1楼拉线费用最少(是k楼)
				// 那么下次,就找哪一楼与k楼拉线费用最少(但是如果还有楼与1楼相连费用更少的话,还是选择与1楼相连,看下面的更新即可明白)
				for (int j = 1; j <= v; j++) {
					if (lowcost[j] != 0 && lowcost[j] < minsum) {
						minsum = lowcost[j];
						k = j;
					}
				}

				// 出口
				if (adjvex[k] == k)
					break;

				sum += minsum;
				adjvex[k] = 0;// 将已经拉线的楼,标记为0

				// 更新lowcost,找那些楼与k楼相连费用少,还是与原先的1楼(这里为了方便理解,写的是1楼,实际上会变的)相连的费用少
				for (int j = 1; j <= v; j++) {
					if (lowcost[j] != 0 && lowcost[j] > map[k][j]) {
						lowcost[j] = map[k][j];
						adjvex[j] = k;
					}
				}
			}
			System.out.println(sum + min);
		}
		sc.close();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值