8.图论——2.kruskal算法dijkstra算法

最小生成树

n个顶点组成的带权无向图,其生成树,即包含全部n个顶点并有n-1条边的无向连通子图。
最小生成树即各边权值和最小的一棵生成树,求最小生成树有kruskal算法和prim算法

kruskal算法

  1. 建立一个并查集,每个顶点一个集合
  2. 把所有边,按照权值大小进行排序
  3. 按照权值从小到大遍历每一条边
    • 若边的顶点<x,y>已经在同一个集合中,那么忽略
    • 若边的顶点<x,y>不在同一个集合中,将该边的权值记录到总和中

对边进行排序

  1. 设计一个边类edge,包含两个顶点x,y,和边权重weight
  2. 设置一个边数组,以便排序
  3. sort edge

例题——还是畅通工程

在这里插入图片描述

代码

#include <cstdio>
#include <string>
#include <map>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
//#include <bits/stdc++.h>
using namespace std;
struct edge{
    int x;
    int y;
    int weight;
};

#define N 1000

int father[N];//存储每个元素父节点的下标
int height[N];//存储某个根的数的高度

void init(int n){
    //最开始的时候,每一个元素都要单独构建一个集合
    for (int i = 0; i < n; ++i) {
        //i的编号从0到n-1
        father[i]=i;//每个元素各自为根
        height[i]=1;//每个树的初始高度都是1
    }
}

int find(int x){
    if (x != father[x]){
        //递归向上找
//        return find(father[x]);
        //find路径压缩,找到祖先(爷爷)后先不返回,把他设为新的父亲
        father[x]= find(father[x]);

    }
    //x就是子树的根
    return father[x];
}

void _union(int x, int y, int weight, int &total){
    //合并两棵树,先要找到y的祖先,再把y祖先的父亲设为x的祖先
//    father[find(y)] = find(x);
    x = find(x);
    y = find(y);
    if (x!=y){
        total+=weight;
    }
    if (height[x]<height[y]){
        father[x]=y;
    } else if (height[x]>height[y]){
        father[y]=x;
    } else{
        father[y]=x;
        ++height[x];
    }
}
bool compare(edge lhs, edge rhs){
    return lhs.weight<rhs.weight;
}

int main() {
    int n;
    while (scanf("%d",&n)!=EOF){
        if (n==0){
            break;
        }
        init(n);
        vector<edge> vec;
        for (int i = 0; i < n*(n-1)/2; ++i) {
            edge e;
            scanf("%d%d%d",&e.x,&e.y,&e.weight);
            vec.push_back(e);
        }
        sort(vec.begin(),vec.end(), compare);
        int total=0;
        for (int i = 0; i < n*(n-1)/2; ++i) {
            _union(vec[i].x,vec[i].y,vec[i].weight,total);
        }
        printf("%d\n",total);
    }
    return 0;
}

dijkstra算法

单源最短路径

  1. 定义一个数组dist[n],记录当前最短路径,起点设为0,其他设置为无穷大:INT_MAX
  2. 遍历起点能够一次到达的所有边,更新dist数组
  3. 下一个结点选择:① dist最小 ② 未访问过(用小根堆存储)
  4. 循环2.3.两步直至所有都访问过,得到最终的dist

例题——畅通工程续

在这里插入图片描述

代码

#include <cstdio>
#include <string>
#include <map>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <climits>
//#include <bits/stdc++.h>
using namespace std;
#define N 300
struct edge{
    int y;
    int weight;
};
struct node{//小根堆专用的类
    int dist;//当前最短距离
    int x;//编号
};
bool operator <(node lhs, node rhs){
    return lhs.dist>rhs.dist;//运算符重载
}

vector<edge> graph[300];
int dijkstra(int s, int t, int n){
    int dist[N];//dist[序号],表示s点到序号点的当前最小距离
    bool visited[N]={false};
    for (int i = 0; i < n; ++i) {
        dist[i] = INT_MAX;
    }
    //小根堆
    priority_queue<node> pq;//第一次访问到某个结点的时候再加入到优先队列中
    //第一个入队的结点是起点
    dist[s] = 0;//起点到起点距离是0
    node no;
    no.dist = dist[s];
    no.x = s;
    pq.push(no);//结点放入小根堆
    //遍历优先队列,每次取出最小的边,考察他的所有边,取出最短的
    //队列为空  时退出
    while(pq.empty()== false){
        int x = pq.top().x;//堆顶的编号(当前距离最小的一个点的编号)
        pq.pop();//出队
        if (visited[x]== true){//如果这个结点已经被访问过,那么就不需要访问它了,直接进入下次循环
            continue;
        }
        visited[x]= true;//未访问过,那么设为已访问
        for (int i = 0; i < graph[x].size(); ++i) {
            //遍历以x为起点的所有关联边
            int y = graph[x][i].y;//x为一端的边的另一端点
            int weight = graph[x][i].weight;//边的权值
            //如果起点到y的距离大于先到x再到y的距离
            if (dist[y]>dist[x]+weight){
                dist[y] = dist[x]+weight;
                no.dist = dist[y];
                no.x=y;
                pq.push(no);
            }
        }
    }
    if (dist[t]!=INT_MAX){
        return dist[t];//终点可达
    } else{
        return -1;//终点不可达,不存在路径
    }
}


int main() {
    int n,m;
    while (scanf("%d%d",&n,&m)!=EOF){
        for (int i = 0; i < n; ++i) {
            graph[i].clear();//清理每个链表中残留的边
        }
        for (int i = 0; i < m; ++i) {
            int x,y,weight;
            scanf("%d%d%d",&x,&y,&weight);
            //将边的信息填入链表
            edge e;
            e.y = y;
            e.weight = weight;
            graph[x].push_back(e);
            e.y = x;
            e.weight = weight;
            graph[y].push_back(e);
        }
        int s,t;
        scanf("%d%d",&s,&t);
        printf("%d\n", dijkstra(s,t,n));
    }
    return 0;
}

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

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

相关文章

vlan间单臂路由

【项目实践4】 --vlan间单臂路由 一、实验背景 实验的目的是在一个有限的网络环境中实现VLAN间的通信。网络环境包括两个交换机和一个路由器&#xff0c;交换机之间通过Trunk链路相连&#xff0c;路由器则连接到这两个交换机的Trunk端口上。 二、案例分析 在网络工程中&#…

一文掌握 TS 高级类型编程

原文地址&#xff1a;github.com/Nealyang/PersonalBlog 前言 或许现在很多同学都在用 TypeScript&#xff0c;但是更可能大多数的同学并不会 TypeScript&#xff0c;他们用的&#xff0c;只不过是给 js 加了一些“注释”&#xff0c;然后洋洋得意“TypeScript 不过如此” 但是…

CSS(四)---【链接美化、浮动布局、三种定位】

零.前言 本篇主要讲解<a>标签链接美化、页面的浮动布局&#xff0c;以及“相对定位”、“绝对定位”、“固定定位”三种定位。 关于其它请查看作者其它文章&#xff1a; CSS(一)---【CSS简介、导入方式、八种选择器、优先级】-CSDN博客 CSS(二)---【常见属性、复合属…

基于springboot实现社区团购系统项目【项目源码+论文说明】

基于springboot实现社区团购系统演示 摘要 本课题是根据用户的需要以及网络的优势建立的一个社区团购系统&#xff0c;来满足用户团购的需求。 本社区团购系统应用Java技术&#xff0c;MYSQL数据库存储数据&#xff0c;基于Spring Boot框架开发。在网站的整个开发过程中&…

水泊梁山108小酒坛之呼保义宋江

宋江【绰号呼保义、及时雨】字公明&#xff0c;是古典名著《水浒传》中的角色。原为山东郓城县押司&#xff0c;他和晁盖互通往来的事被阎婆惜发现&#xff0c;因此怒杀阎婆惜&#xff0c;逃回家隐藏。后前往清风寨投靠花荣&#xff0c;却被清风寨观灯时遭知寨刘高之妻陷害入狱…

LeetCode算法——数组篇

对刷过的算法进行总结&#xff0c;所用解法都是最符合我个人逻辑的&#xff0c;以后再刷的话就看这篇帖子了 # 代码随想录——数组理论基础 首先要知道数组在内存中的存储方式&#xff0c;这样才能真正理解数组相关的面试题 数组是存放在连续内存空间上的相同类型数据的集合 …

基于java+springcloud的分布式架构网上商城

开发语言&#xff1a;Java 框架&#xff1a;springcloud JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Mave…

Gradle连接超时问题connect time out

出现这样的问题不要慌张&#xff0c;可能是你配置gradle的问题一步一步来解决就完事了 1. 出现这样的问题首先我们先检查配置 首先我们先看到的标出来的地址可以看到&#xff0c;我们需要下载的是这个链接里面的压缩包数据&#xff0c;查看版本以及这个链接是不是错误的 2. 第…

springboot核心注解示例详解

文章简介 本文主要介绍springboot框架学习和工作中常用的核心注解&#xff0c;对注解进行了清晰地分类&#xff0c;配以简易代码和易懂的解释&#xff0c;能够让你掌握每个核心注解的用法&#xff0c;并可以迁移到学习和工作中加以使用。本文注解偏向于实用性。 springboot一…

2013年认证杯SPSSPRO杯数学建模B题(第一阶段)流行音乐发展简史全过程文档及程序

2013年认证杯SPSSPRO杯数学建模 B题 流行音乐发展简史 原题再现&#xff1a; 随着互联网的发展&#xff0c;流行音乐的主要传播媒介从传统的电台和唱片逐渐过渡到网络下载和网络电台等。网络电台需要根据收听者的已知喜好&#xff0c;自动推荐并播放其它音乐。由于每个人喜好…

武汉星起航:助力跨境电商新手,打造高质量亚马逊产品评价新策略

在今日全球化与数字化浪潮的推动下&#xff0c;跨境电商已成为推动国际贸易发展的新动力。然而&#xff0c;随着市场竞争的日益激烈&#xff0c;如何让自己的产品在亚马逊平台上脱颖而出&#xff0c;成为了众多跨境电商新手面临的重要问题。武汉星起航电子商务有限公司&#xf…

Qt源码调试步骤记录

1.源码&#xff1a; 两种方式&#xff0c;要么安装qt时选择source&#xff0c;要么从官网下载源码&#xff0c;然后在qt creator中设置路径。二选一即可。我选的第二种。 1.1.第一种&#xff0c;安装时选择source&#xff1a; 1.2.第二种&#xff0c;下载源码设置路径&#x…

MySQL数据库(一)

文章目录 1.MySQL8.0安装配置1.安装教程2.启动方法3.启动注意事项4.Navicat使用5.Navicat演示 2.MySQL数据库基本介绍1.三层结构2.SQL语句分类 3.MySQL数据库基本操作1.创建数据库2.不区分大小写的校对规则3.查看、删除数据库4.备份和恢复数据库1.备份数据库db01和db02&#xf…

C++多线程:线程的创建、join、detach、joinable方法(二)

1、线程的开始与结束 程序运行起来&#xff0c;生成一个进程&#xff0c;该进程所持有的主线程开始自动运行&#xff0c;main主线程运行完所有的代码从main函数中返回表示整个进程运行完毕&#xff0c;标志着主线程和进程的死亡&#xff0c;等待操作系统回收资源&#xff0c;因…

简单了解策略模式

什么是策略模式&#xff1f; 策略模式提供生成某一种产品的不同方式 Strategy策略类定义了某个各种算法的公共方法&#xff0c;不同的算法类通过继承Strategy策略类&#xff0c;实现自己的算法 Context的作用是减少客户端和Strategy策略类之间的耦合&#xff0c;客户端只需要…

ubuntu 连接 校园网

​ 认证修改为 Protected EAP(PEAP) CA 证书 勾选 No CA certificate is required 输入用户名和密码 连接成功 ​

【火猫TV】西甲:巴萨中后场大洗牌,两位新人或被放弃!

巴萨本赛季已经来到了最关键的时刻,联赛中他们要想办法缩小与皇马的差距,欧冠联赛则要和大巴黎争夺四强名额。不过球队在转会市场上的操作非常频繁,在转会资金有限的情况下,他们已经准备了多套引援策略,其中对于中后场的打造可能会成为今夏的工作重心。比如后防核心阿劳霍就被多…

二维码门楼牌管理应用平台建设:智能匹配与高效管理

文章目录 前言一、二维码门楼牌管理应用平台的意义二、地址坐标校验的重要性三、对外采数据匹配校验的实现方式四、智能匹配与人工审核的结合五、二维码门楼牌管理应用平台的前景展望 前言 随着城市化进程的加速&#xff0c;门楼牌管理成为城市治理中不可或缺的一环。传统的门…

java电话号码的字母组合(力扣Leetcode17)

电话号码的字母组合 力扣原题链接 问题描述 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 示例 1&#xff1a;…

HarmonyOS 应用开发之启动/停止本地PageAbility

启动本地PageAbility PageAbility相关的能力通过featureAbility提供&#xff0c;启动本地Ability通过featureAbility中的startAbility接口实现。 表1 featureAbility接口说明 接口名接口描述startAbility(parameter: StartAbilityParameter)启动Ability。startAbilityForRes…