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.mzph.cn/news/681250.shtml

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

相关文章

sklearn:机器学习 分类特征编码category_encoders

文章目录 category_encoders简介OrdinalEncoder 序列编码OneHotEncoder 独热编码TargetEncoder 目标编码Binary Encoder 二进制编码BaseNEncoder 贝叶斯编码LeaveOneOutEncoder 留一法HashingEncoder 哈希编码CatBoostEncoder catboost目标编码CountEncoder 频率编码WOEEncoder…

《Docker极简教程》--Docker镜像--Docker镜像的管理

一、镜像标签与版本管理 1.1 标签的作用与命名规范 标签在Docker镜像中具有标识和版本控制的作用&#xff0c;可以帮助用户识别和管理不同版本的镜像。以下是一些关于Docker镜像标签的常见作用和命名规范&#xff1a; 标识不同版本: 标签通常用于区分不同版本的镜像。例如&a…

Netty应用(九) 之 编解码器概念 Netty常见的编解码器

目录 22.编解码器 22.1 编解码的概念 22.2 netty中的编解码 22.3 序列化 23.编解码器在使用过程中的两部分核心内容 23.1 序列化协议&#xff08;编码格式&#xff09;&#xff08;传输数据的格式&#xff09; 23.1.1 Java默认的序列化与反序列化 23.1.2 XML的序列化与反…

【UI自动化测试技术】自动化测试研究:Python+Selenium+Pytest+Allure,详解UI自动化测试,了解元素交互的常用方法(精)(三)

导言 在之前的文章里&#xff0c;我们一起学习了定位方式、等待机制等内容。相信通过之前的学习&#xff0c;你已经掌握了WEB自动化的一些入门知识&#xff0c;具备了编写代码的一些基础知识和能力。这篇文章&#xff0c;让我们一起学习一下模拟键盘事件。 在实际的项目当中&a…

Ps:焦点堆栈

焦点堆栈 Focus Stacking是一种摄影和图像处理技术&#xff0c;通过合并多张在不同焦距拍摄的照片来创建一张具有更大景深的图像&#xff0c;特别适用于微距摄影、风景摄影和任何需要在整个场景中保持尖锐对焦的情况。 ◆ ◆ ◆ 拍摄注意事项 1、使用三脚架 为了确保图像之间…

嵌入式大厂面试题(2)—— 富士康

从本篇开始将会更新历年来各个公司的面试题与面经&#xff0c;题目来自于网上各个平台以及博主自己遇到的&#xff0c;如果大家有所帮助&#xff0c;帮忙点点赞和关注吧&#xff01; 岗位&#xff1a;嵌入式软件工程师。 面试时间&#xff1a;30分钟。 岗位职责&#xff1a;官网…

django的基本使用-ORM(二)

一、简介 ORM对象关系映射&#xff0c;它允许你使用类和对象对数据库进行操作&#xff0c;从而避免通过SQL语句操作数据库 模型层: 负责和数据库之间进行通信 模型是一个Python类&#xff0c;它是由django.db.models.Model派生出的子类 一个模型类代表数据库中的一张表 模型类…

【Tauri】(3):使用Tauri1.5版本,进行桌面应用开发,在windows上搭建环境,安装node,rust环境,可以打包成功,使用vite创建应用

1&#xff0c;视频地址&#xff1a; https://www.bilibili.com/video/BV1Ny421a7nA/ 【Tauri】&#xff08;3&#xff09;&#xff1a;使用Tauri1.5版本&#xff0c;进行桌面应用开发&#xff0c;在windows上搭建环境&#xff0c;安装node&#xff0c;rust环境&#xff0c;可以…

gstreamer 常用的图片格式转换命令

文章目录 前言一、怎样使用 gstreamer 生成 pattern 数据1. 将 videotestsrc 生成的 pattern 数据送显2. 将 videotestsrc 生成的 pattern 数据保存为图片(文件)二、gstreamer 如何对图片进行格式转换三、gstreamer 如何对图片进行缩放四、gstreamer 如何对图片进行裁剪总结前言…

安全SaaS服务转型的优与劣

文章目录 前言一、ToB的SaaS服务的神话(一)指数级的增长率(二)极低的销售成本二、SaaS 化的真实价值(一)云端数据驱动的AI安全能力建设(二)云端服务规模化带来的价格/效能优势(三)随时随地的统一安全接入与访问总结前言 SaaS化转型似乎是安全行业近十年来最重要的趋…

CorelDRAW2024国内专业个人免费版下载

CorelDRAW是一款屡获殊荣的图形和图像编辑软件&#xff0c;包含两个绘图应用程序&#xff1a;一个用于矢量图及页面设计&#xff0c;另一个用于图像编辑。自1989年进入中国市场以来&#xff0c;CorelDRAW不断推出新的版本和功能&#xff0c;以满足用户不断变化的需求。 CorelD…

【C++计算几何】点是否在线段上

题目描述 输入一个点Q和一条线段P1P2的坐标&#xff0c;判断这个点是否在该线段上。 输入 一行&#xff0c;共六个浮点数&#xff0c;依次表示Q&#xff0c;P1和P2的坐标。 输出 一行&#xff0c;一个字符数&#xff0c;“YES”或“NO”分别表示改点在或者不在线段上。 样…

python从入门到精通(十九):python的多线程详细使用

python的多线程详细使用 1.什么是线程2.线程的作用3.导入线程4.创建线程启动线程线程阻塞线程的方法 守护线程线程阻塞2个都是守护线程1个是守护线程 线程间通信 1.什么是线程 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单…

数字图像处理实验记录十(图像分割实验)

一、基础知识 1、什么是图像分割 图像分割就是指把图像分成各具特性的区域并提取出感兴趣目标的技术和过程&#xff0c;特性可以是灰度、颜色、纹理等&#xff0c;目标可以对应单个区域&#xff0c;也可以对应多个区域。 2、图像分割是怎么实现的 图像分割算法基于像素值的不连…

「Java」static 关键字

介绍 概述&#xff1a;static 是一个静态关键字使用 修饰一个成员变量&#xff1a;static 数据类型 变量名 修饰一个方法 修饰符 static 返回值类型 方法名(形参){方法体 return 结果 }调用静态成员&#xff1a;类名直接调用&#xff08;不用 new 对象&#xff09; static…

ubuntu下如何查看显卡及显卡驱动

ubuntu下如何查看显卡及显卡驱动 使用nvidia-smi 工具查看 查看显卡型号nvida-smi -L $ nvidia-smi -L GPU 0: NVIDIA GeForce RTX 3050 4GB Laptop GPU (UUID: GPU-4cf7b7cb-f103-bf56-2d59-304f8996e28c)当然直接使用nvida-smi 命令可以查看更多信息 $ nvidia-smi Mon Fe…

C# CAD2016获取数据操作BlockTableRecord、Polyline、DBObject

一、数据操作说明 //DBObject 基础类 DBObject dbObj (DBObject)tr.GetObject(outerId, OpenMode.ForRead); //Polyline 线段类 Polyline outerPolyline (Polyline)tr.GetObject(outerId, OpenMode.ForRead); //BlockTableRecord 块表类 BlockTableRecord modelSpace (Bloc…

vue_dev_tools工具下载安装打包

vue_dev_tools工具下载安装打包 一、简介二、安装方式2.1.安装图文2.2.打包工具 endl 一、简介 使用 Vue 时&#xff0c;在浏览器上安装 Vue Devtools Vue Devtools 是 Vue 官方发布的调试浏览器插件&#xff0c;可以安装在 Chrome 和 Firefox 等浏览器上&#xff0c;直接内嵌…

LeetCode Python - 12. 整数转罗马数字

目录 题目答案运行结果 题目 罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#xff0c; 罗马数字 2 写做 II &#xff0c;即为两个并列的 1。1…

去空行小工具Html + Javascript

这是一个平常用到的小工具&#xff0c;为了节省屏幕空间把空行去掉&#xff0c;怕要用的时候找不到故记录在此。 效果图 网页版&#xff0c;放在浏览器里就可以用 <!doctype html> <html><head><meta charset"utf-8"><title>去回车…