POJ 1751 求最小生成树prim算法(JAVA)

题意:
给出N个城镇的坐标和M条已经建好的路, 求连接所有城镇且长度之和最小的高速公路系统的每条公路, 已经存在的公路不用输出。
样例:
Sample Input
9 (城镇个数及坐标)
1 5
0 0
3 2
4 5
5 1
0 4
5 2
1 2
5 3
3 //M条已建好的路,城镇1-->3,9--->7,1--->2
1 3
9 7
1 2

Sample Output

1 6
3 7
4 9
5 7
8 3

由于最后不用输出长度值, 而且坐标的绝对值不超过10000, 所以在算城镇距离的时候就直接省去了sqrt(),由于需要输出MST的边, 所以开了preVex[]记录每个结点的前驱结点, 默认值都为1. 每次选到新的扩展结点min_i后, 若连接它的边权值不为-1, 即这条路是新修建的, 则输出这条边. 然后如果min_i到MST外的某一结点i的权值, 比MST中其它结点到i的权值还要小, 那么更新dis[1][i]): dis[1][i]=dis[min_i][i], 然后顺带更新preVex[i]为min_i.


import java.util.Scanner;
public class Main{
private int dis[][];//邻接矩阵
private int n;//城镇的个数

private boolean vis[]; //城镇已加入到MST的标志

public Main(int n,int[][] dis){
this.n=n;
this.dis=dis;
vis=new boolean[n+1];
}

static int DIS(int x1,int y1,int x2,int y2){//计算两城镇的距离(权)
return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

private void prim(){

int preVex[]=new int[n+1];

vis[1]=true; //城镇1已加入到MST
for(int i=1;i<=n;i++) preVex[i]=1;

for(int k=1;k<n;k++){
int min_i=1;
int min = Integer.MAX_VALUE;
for(int i=1;i<=n;i++){
if(!vis[i] &&dis[1][i]<min) {
min=dis[1][i];
min_i=i;
}
}

vis[min_i]=true; //城镇min_i已加入到MST
if(dis[1][min_i]!=-1) System.out.printf("%d %d\n",preVex[min_i],min_i);
for(int i=1;i<=n;++i)
if(!vis[i] && dis[min_i][i]<dis[1][i]){
dis[1][i]=dis[min_i][i];
preVex[i]=min_i;
}
}
}

public static void main(String[] args){
Scanner in=new Scanner(System.in);


int n=in.nextInt();
int[][] dis=new int[n+1][n+1];

int x[]=new int[n+1];
int y[]=new int[n+1];
for(int i=1;i<=n;i++){//n个城镇的坐标
x[i]=in.nextInt();
y[i]=in.nextInt();
}
int m=in.nextInt();//m条已建好的公路

int u,v;
for(int i=1;i<=m;++i){
u=in.nextInt();
v=in.nextInt();
dis[u][v]=dis[v][u]=-1; //城镇u与v之间已有公路,他们的距离设为-1,必进最小生成树
}
for(int i=1;i<n;++i) {
for(int j=i+1;j<=n;++j)
if(dis[i][j]==0)
dis[j][i]=dis[i][j]=DIS(x[i],y[i],x[j],y[j]);
}


new Main(n,dis).prim();

}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值