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();
}
}
NYOJ--38(图论)-题目--------------------------------布线问题
最新推荐文章于 2018-08-22 18:58:46 发布