教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 golang实现prim算法,计算最小生成树

golang实现prim算法,计算最小生成树

发布时间:2021-05-03   编辑:jiaochengji.com
教程集为您提供golang实现prim算法,计算最小生成树等资源,欢迎您收藏本站,我们将为您提供最新的golang实现prim算法,计算最小生成树资源

golang实现prim算法,计算最小生成树

1、题目描述

给定一个n个点m条边的无向图,图中可能存在重边和自环,边权可能为负数。

求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。

给定一张边带权的无向图G=(V, E),其中V表示图中点的集合,E表示图中边的集合,n=|V|,m=|E|。

由V中的全部n个顶点和E中n-1条边构成的无向连通子图被称为G的一棵生成树,其中边的权值之和最小的生成树被称为无向图G的最小生成树。

输入格式
第一行包含两个整数n和m。

接下来m行,每行包含三个整数u,v,w,表示点u和点v之间存在一条权值为w的边。

输出格式
共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。

2、数据


数据范围
1≤n≤500,
1≤m≤105,
图中涉及边的边权的绝对值均不超过10000。

输入样例:
4 5
1 2 1
1 3 2
1 4 3
2 3 2
3 4 4
输出样例:
6

数据图

1、初始所有点的距离为正无穷,就是代码中的0x3f3f3f3f等于1061109567

2、以第一个点为最初点,绿色表示选中,进入到最小生成树中

3、以第一个更新其他与之连通的点的距离

4、依次迭代

5、最后的最小生成树

3、朴素prim算法步骤时间复杂度O(n^2)

1、先初始化所有点距离为正无穷
2、迭代n次,依次用到集合的最小点更新剩余点距离
3、将已经确定的点加入到st集合中,st数组为一个bool类型

4、代码实现

/*
该图是稠密图,使用邻接矩阵
*/
package main

import (
   "bufio"
   "fmt"
   "os"
   "strconv"
   "strings"
)

const (
   N   = 510
   INF = 0x3f3f3f3f
)

var (
   n, m int
   dist [N]int
   g    [N][N]int
   st   [N]bool
)

func readLine(r *bufio.Reader) []int {
   s, _ := r.ReadString('\n')
   ss := strings.Fields(s)
   res := make([]int, len(ss))
   for i, v := range ss {
      res[i], _ = strconv.Atoi(v)
   }
   return res
}
func prim() int {
   // 初始化距离集合 dist
   for i := 0; i < N; i   {
      dist[i] = 0x3f3f3f3f
   }
   // 迭代n次
   res := 0 //res 存储最小生成树的大小即边的长度总和
   for i := 0; i < n; i   {
      // 找到集合外距离最短的点
      t := -1
      for j := 1; j <= n; j   {
         if !st[j] && (t == -1 || dist[t] > dist[j]) {
            t = j
         }
      }
      // 迭代结束,此时的t就是距离最小点

      // 情况一:图上的点不连通,不能组成最小生成树
      if i > 0 && dist[t] == INF {
         return INF
      } // 如果不是第一个点并且最小店的距离是正无穷,则表示图是不连通的

      if i > 0 {
         res  = dist[t]
      } // 如果不是第一个点,这个t就表示当前点到集合某一个点的最小距离

      // 用最小距离点更新其他跟 "现阶段形成的生成树" 的最短距离,
      //注意更新的顺序,自环是不应该被加到最小生成树,所以,为了避免自环加入最小生成树,提前更新res
      for j := 1; j <= n; j   {
         dist[j] = min(dist[j], g[t][j]) // 此步骤注意是dijkstra的区别,
      }
      st[t] = true

   }
   return res
}
func min(a, b int) int {
   if a >= b {
      return b
   } else {
      return a
   }
}
func main() {
   r := bufio.NewReader(os.Stdin)
   input := readLine(r)
   n, m = input[0], input[1]
   //fmt.Scanf("%d%d\n", &n, &m)
   // 初始化距离
   for i := 0; i < N; i   {
      for j := 0; j < N; j   {
         if i == j {
            g[i][j] = 0
         } else {
            g[i][j] = 0x3f3f3f3f
         }
      }
   }
   //

   for m > 0 {
      m--
      in := readLine(r)
      a, b, c := in[0], in[1], in[2] //输入
      g[a][b] = min(g[a][b], c)
      g[b][a] = g[a][b] // 无向图
   }
   t := prim()
   if t == INF {
      fmt.Println("impossible")
   } else {
      fmt.Println(t)
   }
}
到此这篇关于“golang实现prim算法,计算最小生成树”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
golang实现prim算法,计算最小生成树
数据结构和算法(Golang实现)(29)查找算法-2-3树和左倾红黑树
数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法
数据结构-图(下)-golang
最小耗费生成树
golang sdk后端怎么用_Golang资深后端工程师需要了解的知识点
数据结构-树和二叉树(Golang)
Golang垃圾回收机制
快速部署 Spring PetClinic 到函数计算平台
Golang 编译原理 计算器(通俗易懂)

[关闭]
~ ~