没有合适的资源?快使用搜索试试~ 我知道了~
C++图论专题(form Alex_Wei
需积分: 10 0 下载量 141 浏览量
2022-08-07
12:29:28
上传
评论
收藏 37KB DOCX 举报
温馨提示
试读
13页
最短路(Bellman-Ford,Dijsktra,SPFA,Johnson,Floyd),差分约束,最小生成树(Kruskal,Prim,Boruvka),有向图与无向图连通性(割点,割边,E-BCC 和 SCC 的缩点),欧拉回路。 适合刚接触C++,并对基础数据结构有所了解(栈,二叉树,队列等),对建图有一定要求,需要熟练运用编程语言,掌握如vector,set,map等
资源推荐
资源详情
资源评论
基本定义
� 边导出子图:选出若干条边,以及这些边所连接的所有顶点组成的图称为 边
导出子图。
� 点导出子图:选出若干个点,以及两端都在该点集的所有边组成的图称为 点
导出子图。
� 闭合子图:定义在有向图上。点集 V 导出的 闭合子图 是所有 V 可达的点的
点导出子图。其精确定义为若 x 在子图内,则 x 的所有出点和出边均在子图
内的原图子图;等价于每个点能到的所有点都在子图中。
1. 最短路
最短路是图论最基本的一类问题。
下文记 disu 表示从源点到节点 u 的最短路,n 为节点数 |V|,m 为边数
|E|。
1.1 Bellman-Ford
Bellman-Ford 是一种非常暴力的求解最短路的方法(BF 之于 dijkstra 如同
FF 之于 dinic)。
称一轮 松弛 为对于每一条边 (u,v),用 disu+wu,v 更新 disv。我们断言每轮
至少有一个节点的最短路被更新。松弛 n−1 轮即可。
正确性证明:设源点为 1。在 1→u 的最短路 1→p1→⋯→u 中,对于每个
节点 pi,1→p1→⋯→pi 也一定是 1→p 的最短路,反证法易证。所以一个
节点的最短路一定由另一个节点的最短路扩展而来。因为最短路最多有 n−1
条边,而第 i 轮松弛会得到边数为 i 的最短路,故至多只需松弛 n−1 轮。
该算法还可以判断一张图上是否存在负环。如果在第 n 轮松弛时仍有节点的
最短路被更新,那么图存在负环。
算法的时间复杂度为 O(nm)。
1.2 Dijkstra
dijkstra 是基于 贪心 的最短路算法,适用于 非负权图。
称 扩展 节点 u 为对于 u 的所有出边 (u,v),用 disu+wu,v 更新 disv。
在已经得到最短路的节点中,取出没有扩展过的距离源点最近(即 dis 最小)
的节点并扩展。因为没有负权边,所以取出的节点的最短路长度单调不降。
如何判断一个节点已经取到了最短路?实际上不需要判断,每次取出的节点恰
取到了其最短路。根据边权非负以及 dijkstra 的贪心算法流程,可以通过归纳
法与反证法证明这一点。
归纳假设已经扩展过的节点 p1,p2,⋯,p 在扩展时均取到了其最短路。pk 为
没有被扩展的 dis 最小的节点。
pk 的最短路一定由 pi(1≤i<k) 的最短路扩展而来,不可能出现
dis(pi)+w(pi,pk+1)+w(pk+1,pk)<dis(pj)+w(pj,pk)(1≤i,j<k) 的情况。
否则由于边权非负,w(pk+1,pk)≥0,所以
dis(pi)+w(pi,pk+1)<dis(pj)+w(pj,pk),即当前 dis(pk+1)<dis(pk),与
dis(pk) 的最小性矛盾。
初始令源点的 dis 为 0,假设成立,因此算法正确。
取出 dis 最小的节点的过程可以用优先队列 priority_queue 维护。每次扩展
u 时,若 disu+wu,v<disv,那么将 (v,disu+wu,v) 即节点编号和它更新后的
dis 作为二元组丢进优先队列。尝试取出节点时,以 disu+wu,v 为关键字取
出最小的二元组,则它对应的节点编号就是我们要找的节点。
注意,一个节点可能有多个入边并多次进入优先队列。但当它第一次被取出时,
得到的一定是最短路。为此,需要记录 vis[i] 表示一个节点是否被扩展过。
若当前取出节点已经被扩展过,则忽略。也可以判断是否有当前二元组的第二
个元等于第一个元(节点编号)的 dis,若不等说明当前节点被扩展过了。否
则复杂度将退化为 m2logm。
算法的时间复杂度为 O(mlogm)。
P4779 模板题代码。
//dijkstra
#include <bits/stdc++.h>
using namespace std;
#define pair<int, int> pi;
const int N=1e5+5;
int n,m,s,dis[N];
vector<pi> v[N]
int main(){
cin>>n>>m>>s;
for (int i=1;i<=m;i++){
int n,v,w;
scanf("%d%d%d",&u,&v,&w);
v[u].push_back(make_pair(v,w));
}
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
qriority_queue<pi,vector<pi>,greater<pi>> q;//
优先取权值较小的
pair
q.push(make_pair(0,s));//
注意第一关键字要放到前面
while(!q.empty){
auto t=q.top();
q.pop();
int id=t.second;//
不要搞反了,编号是
second
if (t.first!=dis[id]){
continue;
}
for (auto _ :v[id]){
int it=_.first,d=t.first+_.second;
if(d<dis[it]){
q.push(make_pair(dis[it]=d,it));
}
剩余12页未读,继续阅读
资源评论
世末OIer
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 5G网络基础培训课件.zip
- 2024-spring-HIT-CS-大作业
- yolo目标检测项目实验
- downloadFile-1.hc
- C++课程设计:基于Qt的航班信息管理系统
- ADS7822UVerilog驱动,前面传的有点问题
- 基于python的高性能爬虫程序,使用了多线程+缓存+xpath实现的,这里以彼-岸图库为例,实现,仅用于学习交流
- 中分辨率成像光谱仪(MODIS)烧毁面积产品信息MODIS-C6-BA-User-Guide-1.2.pdf
- Screenshot_20240427_172613_com.huawei.browser.jpg
- 关于学习Python的相关资源网站链接及相关介绍.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功