`
128kj
  • 浏览: 585365 次
  • 来自: ...
社区版块
存档分类
最新评论

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();  
    
  }  
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics