最小生成树之kruskal方法实现 (java)

今天是个阴天,下了点雨,work .........

步骤:将所有边排序,然后不断从小到大加上边,这个过程最重要的是避免环的产生,此处用并查集。(nyoj 38)

  1 package 最小生成树;
  2
  3 import java.util.Arrays;
  4 import java.util.Scanner;
  5 class Node implements Comparable<Node>
  6 {
  7     int x;
  8     int y;
  9     int val;
 10     public Node(int x,int y,int val)
 11     {
 12         this.x=x;
 13         this.y=y;
 14         this.val=val;
 15     }
 16     @Override
 17     public int compareTo(Node o) {
 18         return this.val-o.val;
 19     }
 20
 21
 22 }
 23
 24 public class Main {
 25
 26     public static void init(int a[])//并查集初始化,用来判断是否有环
 27     {
 28         for(int i=1;i<a.length;i++)a[i]=i;
 29
 30     }
 31     public static int find(int a[],int x) //查找节点的父亲,没有优化的方法
 32     {
 33         while(a[x]!=x)
 34         {
 35             x=a[x];
 36         }
 37
 38         return x;
 39     }
 40     public static boolean union(int a[],int x,int y)//union一条边
 41     {
 42         int fx=find(a, x);
 43         int fy=find(a, y);
 44         if(fx!=fy)
 45         {
 46             a[fx]=fy;
 47             return true;  //成功加入
 48
 49         }
 50         return false;//成环
 51
 52     }
 53
 54     public static void main(String[] args) {
 55         // TODO Auto-generated method stub
 56         Scanner scn=new Scanner(System.in);
 57         int len=scn.nextInt();
 58         while(len-->0)
 59         {
 60             int ans=0;//保存最后的答案
 61             int v=scn.nextInt();
 62             int e=scn.nextInt();
 63             Node n[]=new Node[e];
 64             for(int i=0;i<e;i++)
 65             {
 66                 n[i]=new Node(scn.nextInt(),scn.nextInt(),scn.nextInt());
 67
 68
 69             }
 70
 71             Arrays.sort(n);
 72             //并查集的初始化
 73             int father[]=new int[v+1];
 74             init(father);
 75             int index=0;
 76             for(int i=0;i<e;i++)
 77             {
 78                 if(union(father, n[i].x,n[i].y))
 79                 {
 80
 81                     index++; //没成环,加入这条边
 82                     ans+=n[i].val;
 83
 84
 85                 }
 86                 if(index==v-1)
 87                 {
 88                     break;
 89                 }
 90
 91
 92
 93             }
 94             int min=scn.nextInt();
 95
 96             for(int j=1;j<v;j++)
 97             {
 98                 int temp=scn.nextInt();
 99                 if(min>temp) min=temp;
100
101             }
102             System.out.println(ans+min);
103
104         }
105
106     }
107
108
109
110
111 }
时间: 2024-10-08 10:08:57

最小生成树之kruskal方法实现 (java)的相关文章

数据结构(C实现)------- 最小生成树之Kruskal算法

[本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020] 算法描述: Kruskal算法是按权值递增的次序来构造最小生成树的方法. 假设G(V,E)最一个具有n个顶点的连通网,顶点集V={v1,v2,....,vn}.设所求的最小生成树为T={U,TE},其中U是T的顶点集,TE是T的边集,U和TE的初始值为空集.Kruskal算法的基本思想如下:将最小生成树初始化为T=(V,TE),仅包含 G的全部顶点,不包含G的任一条边,此时

ACM:最小生成树,kruskal &amp;&amp; prim,并查集

题目: 输入顶点数目,边的数目,输入每条边的两个顶点编号还有每条边的权值,求最小生成树,输出最小生成树的权值.. 注意:prim算法适合稠密图,其时间复杂度为O(n^2),其时间复杂度与边得数目无关,而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图. kruskal----归并边:prim----归并点 方法一:kruskal,克鲁斯卡尔,并查集实现. #include <iostream> #include <algorithm> using name

最小生成树的Kruskal算法实现

最近在复习数据结构,所以想起了之前做的一个最小生成树算法.用Kruskal算法实现的,结合堆排序可以复习回顾数据结构.现在写出来与大家分享. 最小生成树算法思想:书上说的是在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集(即)且为无循环图,使得的 w(T) 最小,则此 T 为 G 的最小生成树.说白了其实就是在含有 n 个顶点的连通网中选择 n-1 条边,构成一棵极小连通子图,并使该连

poj1861 最小生成树 prim &amp; kruskal

// poj1861 最小生成树 prim & kruskal // // 一个水题,为的只是回味一下模板,日后好有个照应不是 #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #include <iostream> using namespace std; const int MAX_N = 1008; const int INF =

最小生成树之Kruskal算法

上一篇文章中提到了最小生成树的Prim算法,这一节继续探讨一下最小生成树的Kruskal算法.什么是最小生成树算法上文已经交代过了,所以我们直接从Kruskal的步骤开始介绍. 1.Kruskal算法的步骤: a.假定拓扑图的边的集合是E,初始化最小生成树边集合G={}. b. 遍历集合E中的所有元素,并且按照权值的大小进行排序. c. 找出E中权值最小的边e . d .如果边e不和最小生成树集合G中的边构成环路,则将边e加到边集合G中:否则测试下一条权值次小的边,直到满足条件为止. e. 重复

最小生成树 prime kruskal

带权图分为有向和无向 无向图的最短路径又叫做最小生成树,有prime算法和kruskal算法: 有向图的最短路径算法,有dijkstra算法和floyd算法. 生成树的概念:联通图G的一个子图如果是一棵包含G的所有顶点的树,则该子图称为G的生成树 生成树是联通图的极小连通子图.所谓极小是指:若在树中任意增加一条边,则 将出现一个回路:若去掉一条边,将会使之编程非连通图.生成树各边的权 值总和称为生成素的权.权最小的生成树称为最小生成树,常用的算法有prime算法和kruskal算法. 最小生成树

数组翻转的方法(java实现)

数组翻转的方法(java实现),所谓数组翻转,就是将数组倒置,例如原数组为:{"a","b","c","d"},那么翻转后的数组为{"d","c","b","a"}.下面实现方法,这里为了简便我借用了list的add方法. package org.webdriver.autotest.Study; import java.util.ArrayLis

ZOJ 1203 Swordfish 剑鱼行动 最小生成树,Kruskal算法

题目链接:ZOJ 1203 Swordfish 剑鱼行动 Swordfish Time Limit: 2 Seconds      Memory Limit: 65536 KB There exists a world within our world A world beneath what we call cyberspace. A world protected by firewalls, passwords and the most advanced security systems.

最小生成树(kruskal模版 Prim模板)

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2144&cid=1186 最小生成树,最重要的是了解思想 稠密图用Prim,稀疏图用Kruskal K(每次找最小的边连接,一条边连接两个点,所以单路就可以了) 1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 int bin[110]; 5 struct node 6 { 7 int