package Y2018;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/*
题目的背景:
John 的农场缺水!
题目描述:农民 John 决定将水引入到他的 n(1≤n≤300)个牧场。
他准备通过挖若干井,并在各块田中修筑水道来连通各块田地以供水。
在第 i 号田中挖一口井需要花费 W_(i 1≤W_i≤100000)元。
链接 i 号田与 j 号田需要P_ij(1≤P_ij≤100000,P_ji=P_ij)元。
请求出农民 John 需要为连通整个牧场的每一块田地所需要的钱数。
输入格式:
第 1 行为一个整数 n
第 2 行到 n+1 行每行一个整数,从上到下分别为 W_i 到 W_n。
第 n+2 到 2n+1 行为一个矩阵,表示需要的经费(P_ij)。
输出格式:
只有一行,为一个整数,表示所需要的钱数。
*/
public class Main {
private static int n;//农场数
private static int[] farm = new int[310];//农场费用
private static int[][] pipe = new int[310][310];//水管费用
private static boolean[] used = new boolean[310];//默认false,记录已经用过的点
private static List<Integer> points = new ArrayList<>();//存入已经用过的点
private static int minM = 0;//最小费用
public static void main(String args[]) {
Scanner sn = new Scanner(System.in);
n = sn.nextInt();//这是农场个数
for(int i = 0;i < n;i++) {
farm[i] = sn.nextInt();//农场打井的费用
}
for(int i = 0;i < n;i++) {
for(int j = 0;j < n;j++) {
pipe[i][j] = sn.nextInt();//农场与农场之间修水管的费用
}
}
points.add(-1);//将-1认为是虚拟点
for(int i = 0;i < n;i++)//将每一个点都遍历通过
prim();
System.out.println(minM);
sn.close();
}
private static void prim() {
int min = Integer.MAX_VALUE;//记录每一次的最小值
int pos = -2;//记录取最小值所涉及到的最小点
for(int i = 0;i < points.size();i++) {
int point = points.get(i);//循环遍历,选择起点
for(int j = 0;j < n;j++) {
if(!used[j]) {
if(point == -1 && farm[j] < min) {
min = farm[j];
pos = j;
}else if(point != -1 && pipe[point][j] < min) {
min = pipe[point][j];
pos = j;
}
}
}
}
minM += min;
used[pos] = true;
points.add(pos);
System.out.println(min+" "+pos);
}
}