2.13学习总结

1.出差(Bleeman—ford)(spfa)
(dijkstra)
2.最小生成树(prim)(Kruskal)

最短路问题:

出差https://www.luogu.com.cn/problem/P8802

题目描述

AA 国有 �N 个城市,编号为 1…�1…N 小明是编号为 11 的城市中一家公司的员工,今天突然接到了上级通知需要去编号为 �N 的城市出差。

由于疫情原因,很多直达的交通方式暂时关闭,小明无法乘坐飞机直接从城市 11 到达城市 �N,需要通过其他城市进行陆路交通中转。小明通过交通信息网,查询到了 �M 条城市之间仍然还开通的路线信息以及每一条路线需要花费的时间。

同样由于疫情原因,小明到达一个城市后需要隔离观察一段时间才能离开该城市前往其他城市。通过网络,小明也查询到了各个城市的隔离信息。(由于小明之前在城市 11,因此可以直接离开城市 11,不需要隔离)

由于上级要求,小明希望能够尽快赶到城市 NN, 因此他求助于你,希望你能帮他规划一条路线,能够在最短时间内到达城市 �N 。

输入格式

第 11 行:两个正整数 �,�N,M 表示 A 国的城市数量, �M 表示末关闭的路线数量。

第 22 行: �N 个正整数,第 �i 个整数 ��Ci​ 表示到达编号为 ii 的城市后需要隔离的时间。

第 3…�+23…M+2 行: 每行 33 个正整数, �,�,�u,v,c, 表示有一条城市 �u 到城市 �v 的双向路线仍然开通着,通过该路线的时间为 �c。

输出格式

第 11 行:11 个正整数,表示小明从城市 11 出发到达城市 �N 的最短时间。(到达城市 �N,不需要计算城市 �N 的隔离时间)

输入输出样例

输入 #1复制

4 4
5 7 3 4
1 2 4
1 3 5
2 4 3
3 4 5

输出 #1复制

13

说明/提示

【样例说明】

【评测用例规模与约定】

对于 100%100% 的数据, 1≤�≤1000,1≤�≤10000,1≤��≤200,1≤�,�≤1≤N≤1000,1≤M≤10000,1≤Ci​≤200,1≤u,v≤ �,1≤�≤1000N,1≤c≤1000

Dijkstra算法:

主要是利用邻接表和优先队列实现,总复杂度是O(nlongn)

实现:起点先入队,然后找到所有的邻居入队(除了已经标记了找到最短路的),找后序点的时候,优先选择路径短的点(用优先队列实现)

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f
const int N=20010;
int n,m;
int t[N],dist[N];
struct edge{int to;int w;edge(int a,int b) {to=a;w=b;}	
};
vector<edge>e[N];
struct node{int id;int n_dis;node(int aa,int bb){id=aa;n_dis=bb;}bool operator < (const node& a)const{return n_dis > a.n_dis;}
};
void dijkstra(){bool done[N];	//标记数组,用于确定是否该节点找到最短路径 for (int i=1;i<=n;++i){done[i]=false;dist[i]=INF;}dist[1]=0;	//初始化,起点到起点的距离为0 priority_queue<node>q;q.push(node(1,dist[1]));while (!q.empty()){node p=q.top(); q.pop();if (done[p.id]) continue;done[p.id]=true;for (int i=0;i<e[p.id].size();++i){int y=e[p.id][i].to;int w=e[p.id][i].w;if (done[y]) continue;int res=t[y];if (y==n) res=0;if (dist[y]> p.n_dis+w+res){	//当前节点y到起点的最短路径大于路过p点到y点的路径 dist[y]=p.n_dis+w+res;q.push(node(y,dist[y]));}}}
}
signed main(){cin>>n>>m;for (int i=1;i<=n;++i) cin>>t[i];for (int i=0;i<m;++i){	//建立邻接表 int a,b,c;cin>>a>>b>>c;e[a].push_back(edge(b,c));e[b].push_back(edge(a,c));}dijkstra();cout<<dist[n];
} 

Bleeman—ford算法:

复杂度的是O(n^2),相比与floyd算法,该算法主要是找相邻节点,每一轮操作会找到一个最短路径的点,由于有n个点,所以需要进行n次,然后每次需要遍历所有的边。

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
int INF=0x3f3f3f3f;
const int N=20010;
int t[N],dist[N];
struct edge{int a;int b;int c;
}e[N];
signed main(){int n,m;cin>>n>>m;for (int i=1;i<=n;++i) cin>>t[i];for (int i=0;i<m;++i){int a,b,c;cin>>a>>b>>c;e[i].a=a,e[i].b=b,e[i].c=c;e[i+m].a=b,e[i+m].b=a,e[i+m].c=c;}memset(dist,INF,sizeof(dist));dist[1]=0;for (int k=1;k<=n;++k){	for (int i=0;i<2*m;++i){	//双向的 int u=e[i].a,v=e[i].b;int res=t[v];if (v==n)res=0;dist[v]=min(dist[v],dist[u]+res+e[i].c);	}}cout<<dist[n];
} 

SPFA算法:算法复杂度和Dijkstra一样,但是在最坏的情况下会达到O(n^2)是Bleeman—ford的优化,只更新上一轮有变化的点,不更新所有的点

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f
const int N=20010;
int n,m;
int t[N],dist[N];
struct edge{int to;int w;edge(int a,int b) {to=a;w=b;}	
};
vector<edge>e[N];
int inq[N];	//判断是否在队列内 
void spfa(){memset(dist,INF,sizeof(dist));dist[1]=0;queue<int>q;	//队列内存放的是节点号 q.push(1);inq[1]=1;while (!q.empty()){int u=q.front(); q.pop();inq[u]=0;for (int i=0;i<e[u].size();++i){int v=e[u][i].to;int w=e[u][i].w;int res=t[v];if (v==n) res=0;if (dist[v]>res+dist[u]+w){		//只处理更新的节点 dist[v] =dist[u]+w+res;if (!inq[v]){inq[v]=1;q.push(v);}}}}
}
signed main(){cin>>n>>m;for (int i=1;i<=n;++i) cin>>t[i];for (int i=0;i<m;++i){int a,b,c;cin>>a>>b>>c;e[a].push_back(edge(b,c));e[b].push_back(edge(a,c));}spfa();cout<<dist[n];
} 

最小生成树:

最小生成树https://www.luogu.com.cn/problem/P3366

题目描述

如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 orz

输入格式

第一行包含两个整数 �,�N,M,表示该图共有 �N 个结点和 �M 条无向边。

接下来 �M 行每行包含三个整数 ��,��,��Xi​,Yi​,Zi​,表示有一条长度为 ��Zi​ 的无向边连接结点 ��,��Xi​,Yi​。

输出格式

如果该图连通,则输出一个整数表示最小生成树的各边的长度之和。如果该图不连通则输出 orz

输入输出样例

输入 #1复制

4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3

输出 #1复制

7

说明/提示

数据规模:

对于 20%20% 的数据,�≤5N≤5,�≤20M≤20。

对于 40%40% 的数据,�≤50N≤50,�≤2500M≤2500。

对于 70%70% 的数据,�≤500N≤500,�≤104M≤104。

对于 100%100% 的数据:1≤�≤50001≤N≤5000,1≤�≤2×1051≤M≤2×105,1≤��≤1041≤Zi​≤104。

样例解释:

所以最小生成树的总边权为 2+2+3=72+2+3=7。

Prim算法和Kruskal算法的异同

同:都是利用贪心的方式

异:

Prim算法原理:“最小的邻居一定在树上”,从任意一个点u开始,把距离最近的v加入最小生成树中,下一步把距离{u,v}最近的w加入到树中,并且在生成的过程中保证不会生成环路,直到所有的点都在树上

代码与Dijkstra类似

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3fconst int N=4e5+5;
struct edge{int to;int w;edge(int a,int b){to=a;w=b;}
};
vector<edge>e[N];
int n,m,ans;
struct node{int id;int n_dis;	//区别在于Dijkstra这里存的是该节点到起点的最短距离,而Prim中存的是边长(该节点与其他邻居节点的最短边长) node(int a,int b): id(a),n_dis(b){}bool operator < (const node &a)const{return n_dis>a.n_dis;}
};
priority_queue<node>q;
bool done[N];
int dis[N];
void prim(){for (int i=1;i<=n;++i){done[i]=false;dis[i]=INF;}dis[1]=0;q.push(node(1,dis[1]));while (!q.empty()){node p=q.top(); q.pop();if (done[p.id]) continue;done[p.id]=true;ans+=dis[p.id];for (int i=0;i<e[p.id].size();++i){int  v=e[p.id][i].to;int  w=e[p.id][i].w;if (done[v]) continue;if (dis[v]> w){dis[v]=w;q.push(node(v,w));}}}for (int i=1;i<=n;++i){if (!done[i]){cout<<"orz";return;}}cout<<ans;return ;
}signed main(){cin>>n>>m;for (int i=0;i<m;++i){int a,b,c;cin>>a>>b>>c;e[a].push_back(edge(b,c));e[b].push_back(edge(a,c));}prim();
}

Kruskal算法原理:

“最短的边一定在最小生成树上”,从最短的边开始操作,以此加到树中。

算法步骤:先对所有的节点关系进行排序,然后依次把最小的边放到最小生成树中,其中对于是否成环(连通性问题)的判定,可以用并查集实现

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3fconst int N=4e5+5;
int f[N]; 
struct edge{int from;int to;int dis;
};
edge e[N];
bool cmp(const edge& a,const edge& b){return a.dis<b.dis;
}
int find(int x){if (f[x]==x){return x;}else {f[x]=find(f[x]);return f[x];}
}
void unionn(int i,int j){f[find(i)]=find(j);
}
int n,m,ans,cnt;void Kruskal(){for (int i=1;i<=n;++i){f[i]=i;}sort(e+1,e+1+m,cmp);	//排序 for (int i=1;i<=m;++i){	//开始放边 if (find(e[i].from)!=find(e[i].to)){	//如果不会构成环 cnt++;	//节点就放到树上 ans+=e[i].dis;unionn(find(e[i].from),find(e[i].to));	//合并两个节点 }if (cnt==n-1)break;}if (cnt!=n-1) cout<<"orz";else if (cnt==n-1) cout<<ans;
}
signed main(){cin>>n>>m;for (int i=1;i<=m;++i){cin>>e[i].from>>e[i].to>>e[i].dis;}Kruskal();
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

操作系统(16)----磁盘相关

目录 一.磁盘相关概念 1.磁盘 2.磁道 3.扇区 4.盘面、柱面 5.磁盘的分类 二.磁盘调度算法 1.一次磁盘读/写操作需要的时间 2.先来先服务算法(FCFS) 3.最短寻找时间优先(SSTF) 4.扫描算法(SCAN) 5.LOOK调度算法 6.循环扫描算法(C-SCAN) 7.C-LOOK调度算法 三.减少…

【Linux】Kali Linux 系统安装详细教程(虚拟机)

目录 1.1 Kali linux简介 1.2 Kali Linux工具 1.3 VMware workstation和ESXi的区别 二、安装步骤 一、Kali概述 1.1 Kali linux简介 Kali Linux是基于Debian的Linux发行版&#xff0c; 设计用于数字取证操作系统。每一季度更新一次。由Offensive Security Ltd维护和资助。最…

用HTML5 + JavaScript绘制花、树

用HTML5 JavaScript绘制花、树 <canvas>是一个可以使用脚本 (通常为JavaScript) 来绘制图形的 HTML 元素。 <canvas> 标签/元素只是图形容器&#xff0c;必须使用脚本来绘制图形。 HTML5 canvas 图形标签基础https://blog.csdn.net/cnds123/article/details/112…

(C++)集合数据文件存储工具

前言 一个简单的实现简便 "map集合" 数据存储本地。 适合不会SQL但又想实现数据存储本地的同学。 操作使用都非常简单。 文件只做了简单的加密处理&#xff0c;如果需要复杂加密的同学可以修改加密函数。 项目结构 1.创建头文件——CAB.h // // Created by xw o…

云原生介绍与容器的基本概念

云原生介绍 1、云原生的定义 云原生为用户指定了一条低心智负担的、敏捷的、能够以可扩展、可复制的方式最大化地利用云的能力、发挥云的价值的最佳路径。 2、云原生思想两个理论 第一个理论基础是&#xff1a;不可变基础设施。 第二个理论基础是&#xff1a;云应用编排理…

python算法之 Dijkstra 算法

文章目录 基本思想&#xff1a;步骤&#xff1a;复杂度&#xff1a;注意事项&#xff1a;代码实现K 站中转内最便宜的航班 Dijkstra 算法是一种用于解决单源最短路径问题的经典算法。该问题的目标是找到从图中的一个固定顶点&#xff08;称为源点&#xff09;到图中所有其他顶点…

[1-docker-01]centos环境安装docker

官方参考文档 可以在官方docker桌面版本指导文档里找到适合自己的电脑平台进行参考&#xff0c;或者你是老司机的话直接自己上车。 如果不需要桌面版&#xff0c;也可以在官方docker engine版本指导文档里找到适合自己的平台进行参考&#xff0c;同样&#xff0c;老司机可以自…

npm config set registry https://registry.npm.taobao.org 这个设置了默认的镜像源之后如何恢复默认的镜像源

要恢复npm默认的镜像源&#xff0c;你可以使用以下命令将registry设置回npm的官方源&#xff1a; npm config set registry https://registry.npmjs.org/这个命令会修改你的全局npm配置&#xff0c;将包的下载源改回npm官方的源。这样做之后&#xff0c;任何后续的npm install…

C++ bfs再探迷宫游戏(五十五)【第二篇】

今天我们用bfs解决迷宫游戏。 1.再探迷宫游戏 前面我们已经接触过了迷宫游戏&#xff0c;并且学会了如何使用 DFS 来解决迷宫最短路问题。用 DFS 求解迷宫最短路有一个很大的缺点&#xff0c;需要枚举所有可能的路径&#xff0c;读入的地图一旦很大&#xff0c;可能的搜索方案…

安全之护网(HVV)、红蓝对抗

文章目录 红蓝对抗什么是护网行动&#xff1f;护网分类护网的时间 什么是红蓝对抗红蓝对抗演练的目的什么是企业红蓝对抗红蓝对抗价值参考 红蓝对抗 什么是护网行动&#xff1f; 护网的定义是以国家组织组织事业单位、国企单位、名企单位等开展攻防两方的网络安全演习。进攻方…

Vue--》深入学习Tailwind CSS掌握优雅而高效的前端样式开发

Tailwind CSS是一个非常强大且灵活的CSS框架&#xff0c;适用于开发者希望高度定制化界面样式的项目。今天博主就 Tailwind CSS 做一个简单介绍以及案例讲解&#xff0c;争取读者阅读文章后入门。 仅靠一篇文章博主也不可能将Tailwind CSS所有内容讲解的面面俱到&#xff0c;在…

购物|电商购物小程序|基于微信小程序的购物系统设计与实现(源码+数据库+文档)

电商购物小程序目录 目录 基于微信小程序的购物系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户前台功能实现 2、管理员后台功能实现 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 六、论文参考 七、最新计算机毕设…

【力扣】5.最长回文子串

这道题我主要是通过动态规划来进行解题&#xff0c;看了我好久&#xff08;解析&#xff09;&#xff0c;生疏了呀。 首先就是判断一个字符串是不是回文&#xff0c;我们可以设置两个指针&#xff0c;从前往后进行判断即可&#xff0c;运用暴力解题法&#xff0c;这里运用的动…

react【四】css

文章目录 1、css1.1 react和vue css的对比1.2 内联样式1.3 普通的css1.4 css modules1.5 在react中使用less1.6 CSS in JS1.6.1 模板字符串的基本使用1.6.2 styled-components的基本使用1.6.3 接受传参1.6.4 使用变量1.6.5 继承样式 避免代码冗余1.6.6 设置主题色 1.7 React中添…

Redis篇之redis是单线程

一、redis是单线程 Redis是单线程的&#xff0c;但是为什么还那么快&#xff1f;主要原因有下面3点原因&#xff1a; 1. Redis是纯内存操作&#xff0c;执行速度非常快。 2. 采用单线程&#xff0c;避免不必要的上下文切换可竞争条件&#xff0c;多线程还要考虑线程安全问题。 …

【电路笔记】-串联电感

串联电感 文章目录 串联电感1、概述2、电感串联示例13、互耦串联电感器4、电感串联示例25、电感串联示例36、总结当电感器以菊花链方式连接在一起并共享公共电流时,它们可以串联连接在一起。 1、概述 这些电感器的互连产生了更复杂的网络,其总电感是各个电感器的组合。 然而…

CSS Selector—选择方法,和html自动——异步社区的爬取(动态网页)——爬虫(get和post的区别)

这里先说一下GET请求和POST请求&#xff1a; post我们平时是要加data的也就是信息&#xff0c;你会发现我们平时百度之类的 搜索都是post请求 get我们带的是params&#xff0c;是发送我们指定的内容。 要注意是get和post请求&#xff01;&#xff01;&#xff01; 先说一下异…

Linux_进程概念

硬件系统 软件系统 进程概念 进程状态 孤儿进程 进程优先级 一.硬件系统 1.1 冯诺依曼体系结构 数学家冯诺依曼提出了计算机制造的三个基本原则&#xff0c;即采用二进制逻辑、程序存储执行以及计算机由五个部分组成&#xff08;运算器、控制器、存储器、输入设备、输出设备&a…

[Doris] Doris的安装和部署 (二)

文章目录 1.安装要求1.1 Linux操作系统要求1.2 软件需求1.3 注意事项1.4 内部端口 2.集群部署2.1 操作系统安装要求2.2 下载安装包2.3 解压2.4 配置FE2.5 配置BE2.6 添加BE2.7 FE 扩容和缩容2.8 Doris 集群群起脚本 3.图形化 1.安装要求 1.1 Linux操作系统要求 1.2 软件需求 1…

用EXCEL从地址(上海)中提取各区(浦东新区等区)信息

背景&#xff1a; 朋友工作需要经常用EXCEL把各上海用户收货地址中的区提取出来&#xff0c;之前一直手动处理&#xff0c;希望我帮忙用EXCEL公式直接提取处理。 数据样式&#xff1a; 中国上海市浦东新区A小区 上海徐汇区B小区 中国&#xff0c;上海&#xff0c;浦东新区&a…