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

POJ 1789 最小生成树之prim算法

阅读更多
1、生成树
   如果连通图G的一个子图是一棵包含G的所有顶点的树,则该子图称为G的生成树(SpanningTree)。
生成树是连通图的包含图中的所有顶点的极小连通子图,图的生成树不惟一。从不同的顶点出发进行遍历,可以得到不同的生成树。

2、 最小生成树
  对于连通的带权图(连通网)G,其生成树也是带权的。生成树T各边的权值总和称为该树的权,权最小的生成树称为G的最小生成树(Minimum SpannirngTree)。最小生成树可简记为MST。

3、MST性质

   假设N=(V,{E})是一个连通网,U是顶点集合V的一个非空子集。若(u,v)是一条具有最小值(代价)的边,其中u属于U,v属于V-U(即U对立集合),那么必存在一颗包含边(u,v)的最小生成树。

注意prim和kruskal算法都是利用MST性质

Prim算法求最小生成树的基本思想:

  1.首先选取一个点作为起始点,比如说1顶点,加入到U集合中

    2.在所有u∈U,v∈V-U的边(u,v)∈E中,找一条权最小的边(u,v),将此边加进集合T中,并将此边的非U中顶点加入U中。此步骤的功能是在边集E中找一条边,要求这条边满足以下条件:首先边的两个顶点要分别在顶点集合U和V-U中,其次边的权要最小。找到这条边以后,把这条边放到边集T中,并把这条边上不在U中的那个顶点加入到U中。

     3:如果U=V,则算法结束;否则重复步骤2。可以把本步骤看成循环终止条件。我们可以算出当U=V时,步骤2共执行了n-1次(设n为图中顶点的数目),TE中也增加了n-1条边,这n-1条边就是需要求出的最小生成树的边。

例:POJ1789

题意:给出n台卡车的条形码(7位字符串),每两台卡车之间的距离为两条条形码相比较相同位置字符不同的个数,让求出包含所有卡车的最小距离。
Sample Input

4
aaaaaaa
baaaaaa
abaaaaa
aabaaaa
0

Sample Output

The highest possible quality is 1/3.

解题: 如果按照上述关系建立图,节点为卡车的编号,边的权值为卡车之间的距离,很容易将本题目变为求一个图的最小生成树问题了。

import java.util.Scanner;
import java.util.Arrays;
public class Main{
  private int n; //卡车的数目
  private int G[][];//邻接矩阵
  String[] s;//n台卡车的条形码

  public Main(int n,String s[]){
      this.n=n;
      this.s=s;
      G=new int[n+1][n+1];
      init();
     
   }

  private int getdis(String s,String t)/* 得到两台卡车之间的而距离 */
  { 
    int tmp=0; 
    for(int i=0;i<7;i++) 
    { 
        if(s.charAt(i)!=t.charAt(i)) tmp++; 
    } 
    return tmp; 
  } 
  
  public static void main(String args[]){
      Scanner in=new Scanner(System.in);
     while(true){
      int n=in.nextInt();
      if(n==0) break;
      String s[]=new String[n+1];
      for(int i=1;i<=n;i++)
         s[i]=in.next();
      Main m=new Main(n,s);
      System.out.println("The highest possible quality is 1/"+m.prim()+"."); 
     }


   }

    
  private void init(){/* 输入数据 建立邻接矩阵 */ 
    for(int i=1;i<=n;i++){ 
        G[i][i]=Integer.MAX_VALUE; 
        for(int j=i+1;j<=n;j++) 
        { 
            int t=getdis(s[i],s[j]); 
            G[i][j]=G[j][i]=t; 
        } 
    } 
  } 

    public int prim(){
       int sum = 0;
       boolean flag[]=new boolean[n+1];
       flag[1] = true; //选取第一个卡车进入U集
                 
       for(int k=1; k< n; k++){    //循环n-1次,选取n-1条边
         int min = Integer.MAX_VALUE,min_i = 1;
         for(int i=1; i<=n; i++){
           if( !flag[i] && G[1][i] < min){
            min = G[1][i];
            min_i = i;
           }
          }
                
        flag[min_i] = true; //
        for(int i=1; i<= n; i++){ 
          if( !flag[i] && G[1][i] > G[min_i][i]){
              G[1][i] = G[min_i][i];
          }               
       }
              
       sum += G[1][min_i];//加上权值
     }          
            
    return sum;
            
  }
}

源码下载:
分享到:
评论

相关推荐

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

    标题 "POJ 1751 求最小生成树Prim算法(JAVA)" 提到的是一个编程挑战,涉及图论中的经典算法——Prim算法。在计算机科学中,Prim算法是用于寻找加权无向图的最小生成树的一种有效方法。最小生成树是一棵树形结构,...

    POJ1789-Truck History【Prim】

    Prim算法是一种用于求解图中最小生成树的算法。在图论中,一个连通图的最小生成树是一棵树,它包含图中的所有顶点,并且所有边的权重之和尽可能小。Prim算法是从一个顶点开始,逐步添加边,直到包含所有顶点,每次...

    poj1251 最小生成树

    标题“poj1251 最小生成树”是一个编程竞赛题目,来源于著名的在线编程平台POJ(Programming Online Judge)。这个题目主要涉及图论中的一个经典算法问题——最小生成树(Minimum Spanning Tree, MST)。在图论中,...

    POJ2485-Highways【Prim】

    Prim算法可以帮助找到连接所有城市的最短路径总和,即最小生成树。 总的来说,这个压缩包提供了对POJ2485题目的完整解答,通过Prim算法解决了公路网络优化的问题,并附有详细的代码和解题思路。对于学习图论和算法...

    最小生成树题解1

    对于这些题目,理解最小生成树的基本算法如 Prim 和 Kruskal 是关键,同时要注意根据具体问题的特性调整算法的应用。在实际编程时,还需要注意数据结构的选择,例如使用优先队列(二叉堆)优化 Prim 算法,或者使用...

    最小生成树(MST)问题——北京大学暑期课《ACM/ICPC竞赛训练》

    Prim算法是一种贪心算法,其基本思想是从某个顶点出发,逐步选择与当前已构建的生成树相连接的边中权重最小的边加入生成树中,直到生成树包含图中的所有顶点为止。 - **初始化**:选择一个顶点\( v \)作为起始顶点...

    POJ1258-Agri-Net【Prim】

    Prim算法是一种在加权无向图中寻找最小生成树的算法,用于找到连接所有顶点的边之和最小的子集。 **普里姆算法详解:** 普里姆算法是一种贪心算法,它从一个顶点开始,逐步扩展最小生成树,每次添加一条与当前生成...

    度限制最小生成树源码

    Prim算法是求解最小生成树的经典算法之一。在解决度限制最小生成树问题时,需要对Prim算法进行一定的扩展。给定代码片段中使用了Prim算法来计算每个连通分量内的最小生成树,并通过扩展Prim算法(`extend_degree()`...

    poj1789.zip_history

    2. Prim算法:掌握Prim算法的实现细节,如贪心策略,优先队列(例如二叉堆)的应用,以及如何逐步构建最小生成树。 3. C++编程:熟练运用C++语法,包括文件输入/输出,结构体或类的定义,以及动态内存管理等。 4. ...

    POJ2031-Building a Space Station【Prim+计算几何】

    【Prim算法】Prim算法是一种贪心策略,用于解决图论中的最小生成树问题。它从一个初始顶点开始,逐步添加边,每次选择与当前树连接且权重最小的边,直到所有顶点都被包含在内。Prim算法有多种实现方式,如优先队列...

    POJ3026-Borg Maze【BFS+Prim】

    然后,Prim算法每次从尚未加入最小生成树的节点中选择距离起点最近的一个,连接到树中,更新其他节点的距离。重复此过程,直至所有节点都被包含在内。 在提交的代码文件“POJ3026-Borg Maze【BFS+Prim】.cpp”中,...

    POJ算法题目分类

    * 最小生成树算法:最小生成树算法是指计算图的最小生成树的算法,如 prim、kruskal。 * 拓扑排序:拓扑排序是指计算图的拓扑排序的算法,如 poj1094。 * 二分图的最大匹配:二分图的最大匹配是指计算二分图的最大...

    ACMer需要掌握的算法讲解 (2).docx

    * 最小生成树算法:prim、kruskal、POJ1789、POJ2485、POJ1258、POJ3026 * 拓扑排序:POJ1094 * 串算法:POJ1035、POJ3080、POJ1936 * 哈希表和二分查找等高效查找法:POJ3349、POJ3274、POJ2151、POJ1840、POJ2002...

    poj 2485 Highways 测试数据

    1. **Prim算法**:Prim算法是一种贪心策略,从一个初始顶点开始,逐步添加最便宜的边,使得每次添加的新边都连接到已有的最小生成树。这个过程持续到所有顶点都被包含在内。Prim算法在稠密图中效率较高,因为它每次...

    POJ第1861题源码POJ第1861题源码POJ第1861题源码POJ第1861题源码

    常见的求解最小生成树的算法有Prim算法和Kruskal算法。 1. **Prim算法**:从一个顶点开始,逐步添加边,每次添加的边连接两个不同的连通分量,并且具有当前未加入树的边中的最小权重,直到连接所有顶点为止。 2. *...

    次小生成树(POJ 1679 The Unique MST)

    先利用prim算法求出最小生成树,然后通过往MST里加边来判断新生成的最小生成树是否具有最小的权值,POJ上The Unique MST(1679)题是要求判断最小生成树是否唯一,此题其实根本不用这样做,但是为了练习球次小生成树...

    POJ 1639 Picnic Planning 最小度限制生成树

    1. **函数mst(int ss)**:输入参数ss代表生成树的起点,该函数通过Prim算法实现最小生成树的构建。 - 初始化距离数组`dis[]`,设置起点距离为0,其余节点距离为无穷大。 - 使用循环找到未加入生成树的最近节点,并...

    Stoer-Wagner算法求全局最小割(模板)

    prim算法是一种贪心算法,用于计算图的最小生成树。Stoer-Wagner 算法将prim算法应用于计算图的最小割。 Stoer-Wagner 算法的实现可以分为以下步骤: 1. 初始化图的邻接矩阵mat和deleted数组,deleted数组用于标记...

    POJ中级图算法所有题目【解题报告+AC代码】

    2. **最小生成树**:Prim算法和Kruskal算法是两种常见的构建最小生成树的方法。Prim算法从一个顶点开始逐步添加边,而Kruskal算法则是按边的权重从小到大加入,确保不形成环路。 3. **拓扑排序**:对于有向无环图...

Global site tag (gtag.js) - Google Analytics