图论·Day01

P3371
P4779

P3371 【模板】单源最短路径(弱化版)

注意的点:

  • 边有重复,选择最小边!
  • 对于SPFA算法容易出现重大BUG,没有负权值的边时不要使用!!!

70分代码 朴素板dijsktra

  • 爆空间
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n, m, s, u, v, w;
void solve() {cin >> n >> m >> s;vector<vector<int>>grid(n + 9, vector<int>(n + 9, INT_MAX));vector<int>dist(n + 9, INT_MAX);vector<bool>visited(n + 9, false);while (m--) {cin >> u >> v >> w;grid[u][v] = min(grid[u][v], w);}dist[s] = 0;for (int i = 1; i <= n; i++) {int cur = 1;int minDist = INT_MAX;for (int j = 1; j <= n; j++) {if (!visited[j] && dist[j] < minDist) {minDist = dist[j];cur = j;}}visited[cur] = true;for (int j = 1; j <= n; j++) {if (!visited[j] && grid[cur][j] != INT_MAX && dist[cur] + grid[cur][j] < dist[j]) {dist[j] = dist[cur] + grid[cur][j];}}/*cout << "select " << cur << endl;for (int i = 1; i <= n; i++) {cout << dist[i] << " ";}cout << endl;*/}for (int i = 1; i <= n; i++) {cout << dist[i] << " ";}
}
int main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

32分代码 SPFA

  • 因为有重复指向的边,所有理论上边数可以无穷大,O(KM)的时间复杂度不确定性极大!
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n, m, s, u, v, w;
struct Edge {int v, w;Edge(int a, int b) :v(a), w(b) {}
};
void solve() {cin >> n >> m >> s;vector<list<Edge>>grid(n + 9, list<Edge>());vector<int>dist(n + 9, INT_MAX); dist[s] = 0;queue<Edge>q;while (m--) {cin >> u >> v >> w;grid[u].push_back(Edge(v, w));}q.push({ s,0 });while (!q.empty()) {Edge cur = q.front();q.pop();for (auto item : grid[cur.v]) {if (item.w + dist[cur.v] < dist[item.v]) {dist[item.v] = dist[cur.v] + item.w;q.push(item);}}}for (int i = 1; i <= n; i++) {cout << dist[i] << " ";}
}
int main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

AC代码 堆优化dijsktra

  • 重复的边不影响
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n, m, s, u, v, w;
struct Edge {int v, w;Edge(int a, int b) :v(a), w(b) {}
};
class cmp {
public:bool operator()(const Edge& a, const Edge& b) {return a.w > b.w;//从小排序}
};void solve() {cin >> n >> m >> s;vector<list<Edge>>grid(n + 9, list<Edge>());vector<int>dist(n + 9, INT_MAX); dist[s] = 0;vector<bool>visited(n + 9, false);priority_queue<Edge, vector<Edge>, cmp>q;while (m--) {cin >> u >> v >> w;grid[u].push_back(Edge(v, w));}q.push({ s,0 });while (!q.empty()) {Edge cur = q.top();q.pop();if (visited[cur.v]) {continue;}visited[cur.v] = true;for (auto item : grid[cur.v]) {if (!visited[item.v]&&item.w + dist[cur.v] < dist[item.v]) {dist[item.v] = item.w + dist[cur.v];q.push({ item.v,dist[item.v] });}}}for (int i = 1; i <= n; i++) {cout << dist[i] << " ";}
}
int main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

P1144

最短路计数

题目描述

给出一个 N N N 个顶点 M M M 条边的无向无权图,顶点编号为 1 ∼ N 1\sim N 1N。问从顶点 1 1 1 开始,到其他每个点的最短路有几条。

输入格式

第一行包含 2 2 2 个正整数 N , M N,M N,M,为图的顶点数与边数。

接下来 M M M 行,每行 2 2 2 个正整数 x , y x,y x,y,表示有一条连接顶点 x x x 和顶点 y y y 的边,请注意可能有自环与重边。

输出格式

N N N 行,每行一个非负整数,第 i i i 行输出从顶点 1 1 1 到顶点 i i i 有多少条不同的最短路,由于答案有可能会很大,你只需要输出 $ ans \bmod 100003$ 后的结果即可。如果无法到达顶点 i i i 则输出 0 0 0

对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 1 0 6 1\le N\le10^6 1N106 1 ≤ M ≤ 2 × 1 0 6 1\le M\le 2\times 10^6 1M2×106

AC题解 堆优化dijsktra

  • 多一段条件判断,不加入堆但是也起到了统计作用
else if (dist[cur.v] + item.w == dist[item.v]) {ct[item.v] += ct[cur.v];ct[item.v] %= 100003;}
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n, m, x, y;
struct Edge {int v, w;Edge(int a, int b) :v(a), w(b) {};
};
class cmp {
public:bool operator()(const Edge& a, const Edge& b) {return a.w > b.w;}
};
priority_queue<Edge,vector<Edge>,cmp>q;
void solve() {cin >> n >> m;vector<list<Edge>>grid(n+ 9, list<Edge>());vector<bool>visited(n+ 9, false);vector<int>dist(n+9, INT_MAX);vector<int>ct(n+9, 0);while (m--) {cin >> x >> y;grid[x].push_back(Edge(y, 1));grid[y].push_back(Edge(x, 1));}dist[1] = 0; ct[1] = 1;q.push({ 1,0 });while (!q.empty()) {Edge cur=q.top();q.pop();if (visited[cur.v]) {continue;}visited[cur.v] = true;for (auto item : grid[cur.v]) {if (dist[cur.v] + item.w < dist[item.v]) {dist[item.v] = dist[cur.v] + item.w;ct[item.v] = ct[cur.v];q.push({ item.v,dist[item.v] });}else if (dist[cur.v] + item.w == dist[item.v]) {ct[item.v] += ct[cur.v];ct[item.v] %= 100003;}}}//for (int i = 1; i <= n; i++) {//    cout << dist[i] << " ";//}for (int i = 1; i <= n; i++) {cout << ct[i] << endl;}
}
int main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

P5905

【模板】全源最短路(Johnson)

题目描述

给定一个包含 n n n 个结点和 m m m 条带权边的有向图,求所有点对间的最短路径长度,一条路径的长度定义为这条路径上所有边的权值和。

注意:

  1. 边权可能为负,且图中可能存在重边和自环;

  2. 部分数据卡 n n n 轮 SPFA 算法。

输入格式

1 1 1 行: 2 2 2 个整数 n , m n,m n,m,表示给定有向图的结点数量和有向边数量。

接下来 m m m 行:每行 3 3 3 个整数 u , v , w u,v,w u,v,w,表示有一条权值为 w w w 的有向边从编号为 u u u 的结点连向编号为 v v v 的结点。

输出格式

若图中存在负环,输出仅一行 − 1 -1 1

若图中不存在负环:

输出 n n n 行:令 d i s i , j dis_{i,j} disi,j 为从 i i i j j j 的最短路,在第 i i i 行输出 ∑ j = 1 n j × d i s i , j \sum\limits_{j=1}^n j\times dis_{i,j} j=1nj×disi,j,注意这个结果可能超过 int 存储范围。

如果不存在从 i i i j j j 的路径,则 d i s i , j = 1 0 9 dis_{i,j}=10^9 disi,j=109;如果 i = j i=j i=j,则 d i s i , j = 0 dis_{i,j}=0 disi,j=0

右图为样例 2 2 2 给出的有向图,红色标注的边构成了负环,注意给出的图不一定连通。

Johnson算法

  • 数据溢出longlong的转换
  • h[item.v] = h[cur.v] + item.w;这段代码是Johnson算法的精髓,势能函数
  • dist[j] + h[j] - h[st]由于路径上每一个边<i,j>都加入了h[i]-h[j],所以最短距离应该要 + 末位 - 首位,才是最终距离!
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n, m;
ll u,v,w;
void dijsktra(int st,vector<ll>dist);
struct Edge {ll v, w;Edge(ll a, ll b) :v(a), w(b) {};
};
class cmp {
public:bool operator()(const Edge& a, const Edge& b) {return a.w > b.w;}
};
ll inf = ll(1e9);
queue<Edge>q;
vector<int>ct(3009, 0);
vector<list<Edge>>edges(3009, list<Edge>());
vector<ll>h(3009, inf);vector<ll>dist(3009, inf);
priority_queue<Edge, vector<Edge>, cmp>s;
bool visited[3009];
void solve() {cin >> n >> m;while(m--) {cin >> u >> v >> w;edges[u].push_back({ v,w });}for (int i = 1; i <= n; i++) {edges[0].push_back({ i,0 });}h[0] = 0;q.push({ 0,0 }); ct[0] = 1;while (!q.empty()) {Edge cur = q.front();q.pop();if (ct[cur.v] >= n) {cout << -1;return;}for (auto item : edges[cur.v]) {if (h[cur.v] + item.w < h[item.v]) {h[item.v] = h[cur.v] + item.w;ct[item.v] ++;q.push(item);              }}}/*  cout << "h" << endl;for (int i = 0; i <= n; i++) {cout << h[i]<<" ";}cout << endl;*//*重组edges数组*/for (int i = 1; i <= n; i++) {for (auto& item : edges[i]) {item.w = item.w+h[i] - h[item.v];}}for (int i = 1; i <= n; i++) {dijsktra(i,dist);}
}
void dijsktra(int st,vector<ll>dist) {memset(visited, false, sizeof(visited));dist[st] = 0; s.push({ st,0 });while (!s.empty()) {Edge cur = s.top();s.pop();if (visited[cur.v]) {continue;}visited[cur.v] = true;for (auto item : edges[cur.v]) {if (!visited[item.v]&&dist[cur.v] + item.w < dist[item.v]) {dist[item.v] = item.w+ dist[cur.v];s.push({ item.v,dist[item.v] });}}}/*for (int i = 1; i <= n; i++) {cout << dist[i] << " ";}cout << endl;*/ll ans = 0;for (int j = 1; j <= n; j++) {if (dist[j] == inf) {ans += ll(j) * dist[j];}else {ans += ll(j) * (dist[j] + h[j] - h[st]);}}cout << ans << endl;
}
int main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

今日总结

  • dijsktra不能用于负权值
  • Bellman可以用于检测负权回路
  • SFPA算法不要轻易用!容易爆死!
  • Floyd 算法时间复杂度O(n3),dijsktra O(mlogm),Johnson算法时间复杂度接近 O(nmlogn),相当于用SFPA扫除了dijsktra不能求负权值边的障碍,最终还是要归结于dijsktra算法堆优化版来!说人话就是Bellman和SFPA太慢,dijsktra用不了,所以采用Johnson算法!

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

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

相关文章

100 个网络基础知识普及,看完成半个网络高手!

1&#xff09;什么是链接&#xff1f; 链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。 2&#xff09;OSI 参考模型的层次是什么&#xff1f; 有 7 个 OSI 层&#xff1a;物理层&#xff0c;数据链路层&#xff0c;网络层&#xff0…

医疗器械网络安全 | 漏洞扫描、渗透测试没有发现问题,是否说明我的设备是安全的?

尽管漏洞扫描、模糊测试和渗透测试在评估系统安全性方面是非常重要和有效的工具&#xff0c;但即使这些测试没有发现任何问题&#xff0c;也不能完全保证您的医疗器械是绝对安全的。这是因为安全性的评估是一个多维度、复杂且持续的过程&#xff0c;涉及多个方面和因素。以下是…

uniapp实现table排序

根据后端接口传来的数字大小对列表进行升序/降序展示 效果图&#xff0c;价格由高到低降序 价格由低到高 升序 js 降序升序代码如下 export default {data() {return {MtList:[]}},onLoad() {this.MtypeName();//加载列表方法},methods: {MtypeName(){//列表方法this.$api.…

办公技巧:如何编辑带有工作表保护的Excel文件?

在日常工作中&#xff0c;我们经常会遇到带有工作表保护的Excel文件&#xff0c;这些文件虽然可以被打开查看&#xff0c;但无法直接编辑或修改其中的数据。然而&#xff0c;在某些情况下&#xff0c;我们可能需要编辑这些受保护的工作表以满足工作需求。本文将介绍几种方法来编…

【Linux】Linux操作系统

Linux基本指令 os概念与定位 本节内容&#xff1a; Linux操作系统讲解 os概念与定位 操作系统&#xff08;Operating System&#xff0c;简称OS&#xff09;是管理和控制计算机硬件与软件资源的计算机程序。总的来讲&#xff0c;操作系统是一款做软硬件管理的软件。 了解操作…

FastGPT+OneAI接入网络模型

文章目录 FastGPT连接OneAI接入网络模型1.准备工作2.开始部署2.1下载 docker-compose.yml2.2修改docker-compose.yml里的参数 3.打开FastGPT添加模型3.1打开OneAPI3.2接入网络模型3.3重启服务 FastGPT连接OneAI接入网络模型 1.准备工作 本文档参考FastGPT的官方文档 主机ip接…

配置光源——笔记

一、灯光的类型 (一&#xff09;Directional Light&#xff08;定向光&#xff09; 1、只改变方向变化&#xff0c;不记录位置变化 2、相当于太阳光 3、室外一般使用 (二&#xff09;Spot 聚光灯&#xff1a;昏暗&#xff08;凌晨或傍晚&#xff09;&#xff0c;有一个光斑…

科普文:spring boot中常用的接口、工具栏、注解整理

1.springboot 常用接口 1.1 Aware接口 Spring IOC容器中 Bean是感知不到容器的存在&#xff0c;Aware(意识到的)接口就是帮助Bean感知到IOC容器的存在&#xff0c;即获取当前Bean对应的Spring的一些组件&#xff0c;如当前Bean对应的ApplicationContext等。 1.1.1 Applicati…

SSM学习6:Spring事务

简介 事务作用&#xff1a;在数据层保障一系列的数据库操作同成功同失败Spring事务作用&#xff1a;在数据层或业务层保障一系列的数据库操作同成功同失败 public interface PlatformTransactionManager{void commit(TransactionStatus status) throws TransactionStatus ;vo…

数据分析:小红书户外风潮起,内容种草新密码

导语 随着巴黎奥运会临近&#xff0c;小红书顺应热点推出《大家运动会》等S级IP&#xff0c;让户外运动与社区更好地有机融合&#xff0c;为品牌带来更广泛的市场曝光和用户参与度。品牌如何借势热点&#xff0c;完成新一轮的增长呢&#xff1f; S级IP《大家运动会》 千瓜数…

python如何查看类的函数

Python非常方便&#xff0c;它不需要用户查询文档&#xff0c;只需掌握如下两个帮助函数&#xff0c;即可查看Python中的所有函数&#xff08;方法&#xff09;以及它们的用法和功能&#xff1a; dir()&#xff1a;列出指定类或模块包含的全部内容&#xff08;包括函数、方法、…

一个使用Go语言和现代Web技术构建跨平台桌面应用程序开源项目

大家好&#xff0c;今天给大家分享一个使用Go语言和现代Web技术构建跨平台桌面应用程序开源项目Wails。 Wails是一个允许开发者使用Go和Web技术编写桌面应用程序的项目。 它被设计为Go的快速且轻量的Electron替代品&#xff0c;旨在提供一个平台&#xff0c;让开发者可以利用Go…

springcloud使用微服务的搭建

微服务的搭建 1.配置对应信息 Springboot 、springcloud、springcloud alibaba对应关系 https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 2.pom.xml的配置 2.1 总项目pom.xml引入依赖 <parent><groupId>org.sprin…

WindowsMac共享文件夹设置

共享文件夹设置 共享文件夹设置Windows系统设置步骤一&#xff1a;设置共享文件夹步骤二: 访问共享文件夹 Mac系统中设置共享文件夹步骤一&#xff1a;设置共享文件夹步骤二&#xff1a;访问共享文件夹 小贴士结论 共享文件夹设置 有时需要在多台电脑之间共享文件夹&#xff0…

美创科技如何助力高校数据安全体系化升级,标杆实践看这里!

在高校如火如荼的数字化转型建设中&#xff0c;平衡合规与发展的天平&#xff0c;强化数据安全保障&#xff0c;是不可忽视的重要工作。 关于如何有效开展&#xff0c;美创与多所国内一流高校深入实践&#xff0c;本案例作为美创护航高校数据安全的又一典型项目&#xff0c;覆盖…

F4搜索帮助和按条件写sql

1.写SQL * -----增加业务员名字字段------SELECTA~VBELN,C~NAME1_TEXTFROM VBAK AS AINNER JOIN VBPA AS B ON A~VBELN B~VBELNINNER JOIN BUT000 AS C ON B~KUNNR C~PARTNERWHEREB~PARVW Z1AND B~POSNR * AND C~NAME1_TEXT IN S_NAMEINTO TABLE GT_NAME1 .SELECTA~VBE…

汽车免拆诊断案例 | 奥迪 Q7 e-tron无法通过插电式充电器充电

故障现象 车主反映&#xff0c;车辆无法使用自带的插电式充电器充电。&#xff08;这种充电方法是“Mode 2充电”&#xff0c;3针插头&#xff0c;10 A&#xff0c;2.2 kW&#xff09; 接车后验证故障&#xff0c;将Type 2充电插头连接到车辆时&#xff0c;充电口锁定销循环三…

【MySQL】8.复合查询

复合查询 一.基本查询回顾(新增子查询)二.多表查询三.自连接四.子查询1.单列单行子查询2.单列多行子查询——三个关键字3.多列子查询4.在 from 子句中使用子查询 五.合并查询六.总结 一.基本查询回顾(新增子查询) //1.查询工资高于500或岗位为MANAGER的雇员&#xff0c;同时还…

MySQL下载安装

下载 1.进入mysql官网&#xff0c;点击下列链接 2.选择server 3.点击Archives&#xff0c;Archives&#xff0c;选择需要的版本 安装 基本是点下一步&#xff0c;值得注意的几点如下&#xff1a; 1、显示所有准备安装的MySQL相关应用&#xff0c;点击“[Execute]”开始执行安…

从数字化营销与运营视角:看流量效果的数据分析

基于数据打通的“全链路”营销是当下的“时髦”&#xff0c;应用它的前提是什么&#xff1f;深度营销和运营的关键数据如何获得&#xff1f;如何利用数据进行更精准的营销投放&#xff1f;如何利用数据优化投放的效果&#xff1f;如何促进消费者的转化&#xff0c;以及激活留存…