这道题也是一道经典最小生成树的题目,用的prim算法。贵在会方法,并且能准确读懂题,我就读了好久,我犹豫的地方比方说:城镇B,C之间相连有一条路,如果城镇A可以通向C,那它也能通向B。开始我把它理解成了,A必须连着B,之间有条路;也必须连着C,之间有条路,其实不是这样。A通向B或C任何一个城镇就相当于也通向了另一个城镇。这才是最小生成树的意思吗,下面就好弄了。
还有一个地方,就是正在建设的路,那不属于你计算的范畴了,所以这之间的路把它定义成0,方便计算。代码不是最好的,还请各位大牛多多给指点。
import java.util.Scanner;
public class Hdu1102 {
public static void main(String[] args){
Scanner sc=new Scanner (System.in);
while(sc.hasNext()){
int n=sc.nextInt();
int [][] distance=new int[n][n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
distance[i][j]=sc.nextInt();
}
}
int m=sc.nextInt();
for(int i=0;i<m;i++){
int a=sc.nextInt();
int b=sc.nextInt();
distance[a-1][b-1]=distance[b-1][a-1]=0;
}//输入数据结束
int sum1=prim(n,distance);
System.out.println(sum1);
}
}
static int prim(int n,int[][] c){
int[] lowcost =new int[n];//记录当前权值最短数组
int[] closet=new int[n];//临接点数组
boolean [] s=new boolean[n];//标志数组
int sum=0;//用来记录最短路径长度
s[0]=true;
//初始化
for(int i=1;i<n;i++){
lowcost[i]=c[0][i];
closet[i]=0;
s[i]=false;
}
for(int i=1;i<n;i++){
int min=Integer.MAX_VALUE;
int j=1;//用来记录下一个临界点
for(int k=1;k<n;k++){
if(lowcost[k]<min&&!s[k]){
min=lowcost[k];
j=k; //记住下一个临接点
}
}
sum+=c[closet[j]][j];
s[j]=true;
for(int k=1;k<n;k++){
if(c[j][k]<lowcost[k]&&!s[k]){
lowcost[k]=c[j][k]; //更新权值数组
closet[k]=j; //此时的临界点
}
}
}
return sum;
}
}