最小生成树

目录

带权图

带权图java代码实现

最小生成树

Kruskal算法

​切分定理

Kruskal算法的java代码实现

Prim算法

Prim算法的java代码实现

 总结


带权图

 边上的权是附加的额外信息,可以代表不同公路的收费等你需要的信息。

带权图java代码实现

port java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.Scanner;
import java.util.TreeSet;

//暂时支持无向带权图
public class WeightedGraph {
    private int V;
    private int E;
    //TreeMap传入的第二个元素是权值类型
    // 我们这里用的是Integer,具体用什么可以自行修改
    private TreeMap<Integer, Integer>[] adj;

    public WeightedGraph(String file){
        File file = new File(filename);
        try(Scanner scanner = new Scanner(file)){
            V = scanner.nextInt();//读取顶点信息
            if(V < 0) throw new IllegalArgumentException("V must be non-negative");
            adj = new TreeMap[V];
            for(int i = 0; i < V; i++){
                adj[i] = new TreeMap<Integer, Integer>();
            }

            E = scanner.nextInt();//读取边的信息
            if(E < 0) throw new IllegalArgumentException("E must be non-negative");

            for(int i = 0; i < E; i++){
                int a = scanner.nextInt();
                validateVertex(a);
                int b = scanner.nextInt();
                validateVertex(b);//判断合法性
                int wight = scanner.nextInt();//读取权值
                //不要自环边
                if(a == b) throw new IllegalArgumentException("Self Loop is Detected!");
                //不要平行边
                if(adj[a].containsKey(b)) throw new IllegalArgumentException("");

                adj[a].put(b, weight);//传入weight
                adj[b].put(a, weight);
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }
    }
    public void validateVertex(int v) {
        if (v < 0 || v >= V) {
            throw new IllegalArgumentException("vertex" + "is invalid");
        }
    }
        public int V() {return V;}
        public int E() {return E;}

        public boolean hasEdge(int v, int w){
        validateVertex(v);
        validateVertex(w);
        return adj[v].containsKey(w);
        }
        //返回和v相邻的所有顶点
    public Iterable<Integer> adj(int v){
        validateVertex(v);
        return adj[v].keySet();//返回TreeMap中所有的键
    }
    //返回权值
    public int getWeight(int v, int w){
        if(hasEdge(v, w))
        return adj[v].get(w);//获得w这个键对应的权值
        throw new IllegalArgumentException(String.format("no edge %d - %d", v, w));
    }

    public int degree(int v){
        validateVertex(v);
        return adj[v].size();
    }
    public void removeEdge(int v, int w){
        validateVertex(v);
        validateVertex(w);
        adj[v].remove(w);
        adj[w].remove(v);
    }
    @Override
    public Object clone(){
        try{
            WeightedGraph cloned = (WeightedGraph) super.clone();
            cloned.adj = new TreeMap[V];
            for(int v = 0; v < V; v++){
                cloned.adj[v] = new TreeMap<Integer, Integer>();
                for(Map.Entry<Integer, Integer>entry : adj[v].entrySet())
                    cloned.adj[v].put(entry.getKey(), entry.getValue());
            }
            return cloned;
        }
        catch(CloneNotSupportedException e){
            e.printStackTrace();
        }
        return null;
    }
    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("V = %d, E = %d\n"), V, E);
        for(int v = 0; v < V; v++){
            sb.append(String.format("%d : ", v));
            for(Map.Entry<Integer, Integer>entry : adj[v].entrySet())
                sb.append(String.format("(%d : %d)", entry.getKey(), entry.getValue()));
            sb.append('\n');
        }
        return sb.toString();
    }

      public static void main(String[]args){
        WeightedGraph g = new WeightedGraph("g.txt");
        System.out.println(g);
      }

}

最小生成树

Kruskal算法

同一张图的不同生成树的权值和大小不同,最小生成树就是求权值和最小的生成树。

在选最短的边的同时要注意不要和已选的边形成环。如下图,我们成功选了六条边连接了七个顶点,形成了最小生成树。

 切分定理

 Kruskal算法的java代码实现

import java.util.ArrayList;
import java.util.Collections;

public class Kruskal {

    private WeightedGraph G;
    private ArrayList<WeightedEdge> mst;

    public Kruskal(WeightedGraph G){

        this.G = G;
        mst = new ArrayList<>();

        CC cc = new CC(G);
        if(cc.count() > 1) return;

        ArrayList<WeightedEdge> edges = new ArrayList<>();
        for(int v = 0; v < G.V(); v ++)
            for(int w: G.adj(v))
                if(v < w)
                    edges.add(new WeightedEdge(v, w, G.getWeight(v, w)));

        Collections.sort(edges);

        UF uf = new UF(G.V());
        for(WeightedEdge edge: edges){
            int v = edge.getV();
            int w = edge.getW();
            if(!uf.isConnected(v, w)){
                mst.add(edge);
                uf.unionElements(v, w);
            }
        }
    }

    public ArrayList<WeightedEdge> result(){
        return mst;
    }

    public static void main(String[] args){

        WeightedGraph g = new WeightedGraph("g.txt");
        Kruskal kruskal = new Kruskal(g);
        System.out.println(kruskal.result());
    }
}

 

Prim算法

Prim算法的java代码实现

import java.util.ArrayList;
import java.util.Queue;
import java.util.PriorityQueue;

public class Prim {

    private WeightedGraph G;
    private ArrayList<WeightedEdge> mst;

    public Prim(WeightedGraph G){

        this.G = G;
        mst = new ArrayList<>();

        CC cc = new CC(G);
        if(cc.count() > 1) return;

        boolean visited[] = new boolean[G.V()];
        visited[0] = true;
        Queue pq = new PriorityQueue<WeightedEdge>();
        for(int w: G.adj(0))
            pq.add(new WeightedEdge(0, w, G.getWeight(0, w)));

        while(!pq.isEmpty()){

            WeightedEdge minEdge = (WeightedEdge) pq.remove();
            if(visited[minEdge.getV()] && visited[minEdge.getW()])
                continue;

            mst.add(minEdge);

            int newv = visited[minEdge.getV()] ? minEdge.getW() : minEdge.getV();
            visited[newv] = true;
            for(int w: G.adj(newv))
                if(!visited[w])
                    pq.add(new WeightedEdge(newv, w, G.getWeight(newv, w)));
        }
    }

    public ArrayList<WeightedEdge> result(){
        return mst;
    }

    public static void main(String[] args){

        WeightedGraph g = new WeightedGraph("g.txt");
        Prim prim = new Prim(g);
        System.out.println(prim.result());
    }
}

 总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/153712.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql---squid代理服务器

squid代理服务器 nginx也可以代理&#xff1a;反向代理--------负载均衡 squid:正向代理服务器。例&#xff1a;vpn squid &#xff1a;正向代理&#xff0c;缓存加速&#xff0c;acl过滤控制 代理的工作机制 1、代替客户端向网站请求数据&#xff0c;不需要访问代理的IP地址…

AI时代,如何防范诈骗的建议

以下是一些防范AI诈骗的方法&#xff1a; 认知教育&#xff1a;了解AI技术的应用和局限性&#xff0c;学习如何识别虚假信息和诈骗手段。保护个人信息&#xff1a;不要轻易泄露个人信息&#xff0c;尤其是身份证号码、银行卡号等敏感信息。谨慎对待陌生人的联系和信息&#xf…

前后端分离项目在Linux的部署方法、一台Nginx如何部署多个Web应用

需求场景:目前有三个前后端分离项目(vue+springboot),Linux服务器一台,nginx一个,比如服务器地址为www.xxxxxxx.com 我想通过80端口访问服务①(即访问www.xxxxxxx.com);通过81端口访问服务②(即www.xxxxxxx.com:81);通过82端口访问服务③(即www.xxxxxxx.com:82) ①部…

Java抽象类和接口

抽象类 看看这个代码 class Shape{public void draw(){System.out.println("画图形");} } class Cycle extends Shape{Overridepublic void draw() {System.out.println("⚪");} } class Rect extends Shape{Overridepublic void draw() {System.out.pri…

一个集成了AI和BI报表功能的新一代数据库管理系统神器--Chat2DB

世人皆知Navicate&#xff0c;无人识我Chat2DB &#x1f4d6; 简介 Chat2DB 是一款开源免费的多数据库客户端工具&#xff0c;支持多平台和主流数据库。 集成了AI的能力&#xff0c;能进行自然语言转SQL、SQL解释、SQL优化、SQL转换 ✨ 好处 1、AIGC和数据库客户端的联动&am…

[Vue 代码模板] Vue3 中使用 Tailwind CSS + NutUI 实现侧边工具栏切换主题

文章归档&#xff1a;https://www.yuque.com/u27599042/coding_star/vzkgy6gvcnpl3u2y 效果示例 配置 src 目录别名 https://www.yuque.com/u27599042/coding_star/ogu2bhefy1fvahfv 配置 Tailwind CSS https://www.yuque.com/u27599042/coding_star/yqzi9olphko9ity1 配置…

各地区农村及城镇恩格尔系数数据集(1978-2022年)

恩格尔系数是以德国统计学家恩格尔&#xff08;Ernst Engel&#xff09;的名字命名的一个经济指标&#xff0c;用来衡量食品支出占家庭总支出的比例。一般来说&#xff0c;恩格尔系数越低&#xff0c;表明家庭在食品上的支出占比越小&#xff0c;相对而言家庭的生活水平和经济条…

StringBuffer和StringBuilder的区别与联系

文章目录 区别一览StringBuffer如何实现多线程同步关键字&#xff08;Synchronized&#xff09;性能考虑使用场景 当不使用多线程的情况下&#xff0c;是否StringBuffer和StringBuilder的性能一样&#xff1f;性能差异原因实践中的选择结论 区别一览 StringBuffer 和 StringBu…

Unity Quaternion接口API的常用方法解析_unity基础开发教程

Quaternion接口的常用方法 Quaternion.Euler()Quaternion.Lerp()Quaternion.Inverse()Quaternion.RotateTowards() Quaternion在Unity中是一种非常重要的数据类型&#xff0c;用于表示3D空间中的旋转。Quaternion可以表示任何旋转&#xff0c;无论是在哪个轴上旋转多少度&#…

fablic 矩形多边形展示删除按钮

标注的矩形框或者多边形框展示删除按钮&#xff1b; 官网有一个例子 我原本想着按照他这个思路&#xff0c;很简单的&#xff1b; 可是当我在使用的过程中&#xff0c;遇到了一些问题&#xff0c;多变想不展示删除按钮&#xff1b;并且如果之前有矩形&#xff0c;无法渲然删除按…

拿走吧你,Fiddler模拟请求发送和修改响应数据

fiddler模拟伪造请求 方法一&#xff1a;打断点模拟HTTP请求 1、浏览器页面填好内容后&#xff08;不要操作提交&#xff09;&#xff0c;打开fiddler&#xff0c;设置请求前断点&#xff0c;点击菜单fiddler,”Rules”\”Automatic Breakpoints”\”Before Requests” 2、在…

问题总结(持续更新)

Linux 1.虚拟机问题 打开虚拟机所在目录对 后缀 .vmx文件进行修改 vmcio.present"FALSE" 改为FALSE即可 2.因某些问题导致本来正常的虚拟机没有网络了 重新配置网络 vim /etc/sysconfig/network-scripts/ifcfg-enstab补全 service network restart 重启网络 Sentina…

海外推广必备|如何制定领英LinkedIn营销战略?

在网络上脱颖而出不是一件简单的事。不仅有比以往更多的平台、算法和内容类型&#xff0c;而且还有更多的企业在争夺注意力。据统计&#xff0c;每天有超过 270 万家公司在 LinkedIn 上发布信息。 策略很重要&#xff0c;尤其是在 LinkedIn 营销领域。下面将为你总结LinkedIn 营…

操作系统OS/进程与线程/线程

进程和线程 进程 进程实体&#xff08;进程映像&#xff09;由PCB、程序段和数据段组成&#xff0c;其中PCB是进程存在的唯一标志。 线程 线程最直接的理解就是“轻量级进程”&#xff0c;它是一个基本的CPU执行单元&#xff0c;包含CPU现场(状态)&#xff0c;也是程序执行…

uniapp Android如何打开常用系统设置页面?

uniapp Android 如何打开常用系统设置页面&#xff1f; 在使用App过程时&#xff0c;有时候会对一些权限获取&#xff0c;比如打开蓝牙、打开通知栏通知等设置&#xff0c;我们如何快速跳转到需要的设置页面&#xff1f; 文章目录 uniapp Android 如何打开常用系统设置页面&…

500mA 线性锂电充电芯片 DP4054/DP4054H完全兼容替代TP4054

锂电池是一种新型的可充电电池&#xff0c;其具有体积小、重量轻、容量大耐用性强等特点&#xff0c;因此被广泛应用于手机、笔记本电脑、移动电源等电了设备上。 充电原理是指电池在充电过程中&#xff0c;用电流将锂离子从外部电源输入电池&#xff0c;使其形成 一个电荷差&…

【LeetCode刷题-滑动窗口】--424.替换后的最长重复字符

424.替换后的最长重复字符 方法&#xff1a;滑动窗口 右边界先移动找到一个满足题意的可以替换k个字符以后&#xff0c;所有字符都变成一样的当前看来最小的子串&#xff0c;直到右边界纳入一个字符以后&#xff0c;不能满足的时候停下然后考虑左边界右移&#xff0c;左边界只…

阿里5年经验之谈 —— 记录一次jmeter压测的过程!

在软件架构与中间件实验的最后&#xff0c;要求进行非功能测试&#xff0c;那得非压力测试莫属了。虽然之前学习秒杀项目的时候看视频里面用过jmeter&#xff0c;但没有自己实操过&#xff0c;趁着这次机会&#xff0c;使用一下。 QPS与TPS 1、TPS&#xff1a; Transactions …

matlab如何实现任意长序列所有排列方式

最近被问到一个问题&#xff0c;如何计算一个由3个0和3个1组成的序列的所有组合情况&#xff0c;处理这个问题我没有找到特别恰当的函数&#xff08;如果有能直接做的函数欢迎评论告知&#xff09;&#xff0c;所以采用比较接近需求的perms函数来解决这个问题 首先看perms函数…

小望电商通:无代码开发,轻松实现电商平台、客服系统和用户运营的集成

无缝连接电商系统和客服系统&#xff0c;轻松实现集成 小望电商通是一款具有突破性的电商解决方案。它为电商行业提供了新的可能性&#xff0c;尤其在电商系统和客服系统的无缝连接和集成上具有显著优势。小望电商通的运用&#xff0c;使企业无需进行任何API开发&#xff0c;就…