Java中的图论2——Kruskal算法

Java中的Kruskal------最小生成树

  • [Kruskal ------ 最小生成树/图](#Kruskal —— 最小生成树/图)
  • [例题1(FROM 洛谷 P3366)](#例题1(FROM 洛谷 P3366))

图论的第一篇是前一章的 -> Java中的 Dijkstra 算法,还打算写一个Floyd,在图论的最后一章会总结三种算法在什么情况下适合使用,以及使用方法,加深记忆。

Kruskal ------ 最小生成树/图

学过离散数学的应该知道什么是最小生成树/图,假设有n个节点,画n-1条边使得该树/图最后的总权重最小的,就是最小生成。Kruskal 算法其实是图论思想和并查集 的结合。并查集不会的可以去补一下 ->Java中的并查集

例题1(FROM 洛谷 P3366)


这就是个模板题,没有什么思路,可以直接看代码

代码实现

java 复制代码
import java.util.*;
import java.io.*;

public class Main{
    static int [] p;
    static BufferedReader bf  = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    
    public static void main(String [] args) throws IOException{
        int n = Integer.parseInt(next());
        int m = Integer.parseInt(next());
        int [][] e = new int [m][3];//{u,v,w};
        for(int i=0;i<m;i++){
            int u = Integer.parseInt(next());
            int v = Integer.parseInt(next());
            int w = Integer.parseInt(next());
            e[i] = new int []{u,v,w};
        }
        Arrays.sort(e,(a,b)->a[2]-b[2]);//将接收到的边按照权重从小到大排序
        
        p = new int [n+1];
        for(int i=1;i<=n;i++)
            p[i] = i;
            
        long ans = 0;//结果
        int count  = 0;//边的个数
        for(int [] E:e){
            int u = E[0];
            int v = E[1];
            int w = E[2];
            if(find(u) != find(v)){//如果没在最小生成图里
                union(u,v);//加进去
                ans += w;//结果加上该边的权重
                count++;//边数加一
                if(count == n-1) break;//如果已经找到了n-1条边,提前结束,剪枝
            }
        }
        if(count < n-1)//如果找到的边不够,说明该图不连通
            System.out.print("orz");
        else System.out.print(ans);
    }
    static int find(int x){
        if(x == p[x]) return x;
        else return p[x] = find(p[x]);
    }
    static void union(int x,int y){
        int rx = find(x);
        int ry = find(y);
        if(rx != ry)
            p[rx] = ry;
    }
    static String next() throws IOException{
        while(st == null || !st.hasMoreTokens()){
            String str = bf.readLine();
            if(str == null) return null;
            st = new StringTokenizer(str);
        }
        return st.nextToken();
    }
}

进阶版: 洛谷 P2820,自行练习吧,代码我贴这里了:

java 复制代码
import java.util.*;
public class Main{
    static int [] p;
    public static void main(String [] args){
        Scanner input = new Scanner (System.in);
        int n = input.nextInt();
        int k = input.nextInt();
        int [][] f = new int [k][3];
        long sumM = 0;
        for(int i=0;i<k;i++){
            f[i][0] = input.nextInt();//i
            f[i][1] = input.nextInt();//j
            f[i][2] = input.nextInt();//m
            sumM += f[i][2];
        }
        Arrays.sort(f,(a,b)->a[2]-b[2]);
        p = new int [n+1];
        for(int i=0;i<=n;i++)
            p[i] = i;
        
        long ans = 0;
        int count = 0;
        for(int i=0;i<k;i++){
            int u = f[i][0];
            int v = f[i][1];
            int w = f[i][2];
            if(find(u) != find(v)){
                union(u,v);
                ans += w;
                count ++;
                if(count == n-1) break;
            }
        }
        System.out.print(sumM-ans);
    }
    static int find(int x){
        if(x == p[x]) return x;
        else  return p[x] = find(p[x]);
    }
    static void union(int x,int y){
        int rx = find(x);
        int ry = find(y);
        if(rx != ry)
            p[rx] = ry;
    }
}

只要学好并查集 so easy

相关推荐
weixin_433431442 小时前
Centos Stream9 + Docker 配置 OpenClaw完整流程
java·开发语言
gelald2 小时前
Spring - IoC 容器原理
java·后端·spring
她说..2 小时前
排查接口响应慢问题
java·jvm·spring boot·spring cloud·java-ee
XiYang-DING2 小时前
【LeetCode】206. 反转链表
算法·leetcode·链表
星如雨グッ!(๑•̀ㅂ•́)و✧2 小时前
Reactor背压
java·服务器·前端
wangchunting2 小时前
数据结构-散列表
java·数据结构·散列表
啥咕啦呛2 小时前
java打卡学习6:集合框架 Collection
java·windows·学习
曹牧2 小时前
Tomcat连接池异常排查
java·tomcat