图论·Day01

news2025/2/23 18:51:55

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.coloradmin.cn/o/1902344.html

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

相关文章

【Web】

1、配仓库 [rootlocalhost yum.repos.d]# vi rpm.repo ##本地仓库标准写法 [baseos] namemiaoshubaseos baseurl/mnt/BaseOS gpgcheck0 [appstream] namemiaoshuappstream baseurlfile:///mnt/AppStream gpgcheck0 2、挂载 [rootlocalhost ~]mount /dev/sr0 /mnt mount: /m…

类与对像(1)

好几个月没有写了&#xff0c;差了好多&#xff0c;这些天补回来吧。 接下来&#xff0c;让我们正式步入C与C语言开始不同的地方。 我对类的理解&#xff1a;类是对于具有相同或相似属性的数据集合。 类的关键词&#xff1a;class&#xff0c;public&#xff0c;protected&a…

vue3中pinia使用持久化管理

安装插件 npm install pinia pinia-plugin-persistpinia进行注册 创建index.ts import { createPinia } from pinia; //对外暴露大仓库 export default createPinia(); 在mian.ts //引入pinpa import { createApp } from vue //引入根组件 import App from ./App.vue const…

昇思MindSpore学习入门-评价指标

当训练任务结束&#xff0c;常常需要评价函数&#xff08;Metrics&#xff09;来评估模型的好坏。不同的训练任务往往需要不同的Metrics函数。例如&#xff0c;对于二分类问题&#xff0c;常用的评价指标有precision&#xff08;准确率&#xff09;、recall&#xff08;召回率&…

全网最详细的appium 自动化测试iOS(二)

一、环境准备&#xff1a; 1、安装appium 2、xcode (appium 版本&#xff1a;12.1.0 xcode版本&#xff1a;12.5 可正常运行&#xff0c;ps:appium 版本&#xff1a;12.1.0 xcode版本&#xff1a;13.0 一直报奇奇怪怪的错误&#xff09; 3、依赖工具包安装 brew install…

基于星火大模型的群聊对话分角色要素提取挑战赛

赛事任务与数据 2024 iFLYTEK A.I.开发者大赛-讯飞开放平台 (xfyun.cn) 从给定的<客服>与<客户>的群聊对话中, 提取出指定的字段信息&#xff0c;待提取的全部字段见下数据说明。 赛题方提供了184条真实场景的群聊对话数据以及人工标注后的字段提取结果&#xf…

linux centos 安装niginx并且添加ssl(https)模块

文章目录 前言一、nginx安装教程1.流程步骤 总结 前言 一、nginx安装教程 1.流程步骤 代码如下&#xff08;示例&#xff09;&#xff1a; 1.先下载linux安装包 2.解压安装命令 sudo tar -zxvf nginx-1.20.1.tar.gz3.进入解压后的目录 sudo cd nginx-1.20.14.安装 sudo y…

opencv环境搭建-python

最近遇到了一些图像处理的需求&#xff0c;所以需要学习一下opencv,来记录一下我的学习历程。 安装numpy pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy安装matplotlib pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib安装opencv …

CSS技巧:用CSS绘制超写实的酷炫徽章缎带效果,超漂亮,超酷炫

为什么要用CSS来画个徽章&#xff1f;这货脑子进水了吧&#xff01; 今天在电脑前设计&#xff0c;要做徽章效果。突然觉得可以尝试用css实现近似的效果。说干就干&#xff0c;打开编辑器&#xff0c;让我的手指头活跃起来&#xff01; 技术要点 通过多个圆形嵌套和渐变属性…

Google Earth Engine(GEE)——在控制台打印出来所选区域的缩略图

结果 函数 ui.Thumbnail(image, params, onClick, style) A fixed-size thumbnail image generated asynchronously from an ee.Image. Arguments: image (Image, optional): The ee.Image from which to generate the thumbnail. Defaults to an empty ee.Image. param…

MySQL 集群

MySQL 集群有多种类型&#xff0c;每种类型都有其特定的用途和优势。以下是一些常见的 MySQL 集群解决方案&#xff1a; 1. MySQL Replication 描述&#xff1a;MySQL 复制是一种异步复制机制&#xff0c;允许将一个 MySQL 数据库的数据复制到一个或多个从服务器。 用途&…

优化LabVIEW代码以提高软件性能

优化LabVIEW代码对于提高软件性能、减少执行时间和资源消耗至关重要。以下是一些具体的策略和方法&#xff0c;可以帮助LabVIEW程序员优化代码&#xff1a; 1. 代码结构和模块化 使用子VI&#xff1a;将重复使用的代码段封装成子VI&#xff0c;提高代码的可读性和可维护性。 避…

星光云VR全景系统源码

星光云VR全景系统源码 体验地址请查看

11 docker安装redis

目录 安装redis 1. 配置redis配置文件redis.conf 1.1. 找到redis.conf文件 1.2. 配置文件 2. 启动容器 3. 测试redis-cli连接 4. 证明docker使用的是指定的配置文件 安装redis 1. 配置redis配置文件redis.conf 1.1. 找到redis.conf文件 宿主机创建目录/app/redis在/a…

vb.netcad二开自学笔记1:万里长征第一步Hello CAD!

已入门的朋友请绕行&#xff01; 今天开启自学vb.net 开发autocad&#xff0c;网上相关资料太少了、太老了。花钱买课吧&#xff0c;穷&#xff01;又舍不得&#xff0c;咬牙从小白开始摸索自学吧&#xff0c;虽然注定是踏上了一条艰苦之路&#xff0c;顺便作个自学笔记备忘!积…

[AI Perplexica] 安装指南:轻松部署AI驱动的开源搜索引擎

[AI Perplexica] AI驱动的开源搜索引擎[AI Perplexica] 深入解析&#xff0c;AI 架构揭秘 之前&#xff0c;我们看过了 Perplexica 的介绍&#xff0c;特点和架构&#xff0c;了解了其工作原理。 今天&#xff0c;我们一起来部署下 安装 docker 安装 docker https://docs.…

2024年江苏省研究生数学建模竞赛B题火箭烟幕弹运用策略优化论文和代码分析

经过不懈的努力&#xff0c; 2024年江苏省研究生数学建模竞赛B题火箭烟幕弹运用策略优化论文和代码已完成&#xff0c;代码为B题全部问题的代码&#xff0c;论文包括摘要、问题重述、问题分析、模型假设、符号说明、模型的建立和求解&#xff08;问题1模型的建立和求解、问题2模…

RabbitMQ快速入门 - 图像化界面的简单操作

目录 1、RabbitMQ的安装 2、RabbitMQ基本介绍 3、简单案例 4、数据隔离 1、RabbitMQ的安装 官网链接&#xff1a;rabbitmq官网 &#xff08;官网很详细&#xff0c;也可以在官网学习啦~&#xff09; 基础入门&#xff1a;自主学习&#xff1a;最新版本&#xff1a;安装我…

基于支持向量机、孤立森林和LSTM自编码器的机械状态异常检测(MATLAB R2021B)

异常检测通常是根据已有的观测数据建立正常行为模型&#xff0c;从而将不同机制下产生的远离正常行为的数据划分为异常类&#xff0c;进而实现对异常状态的检测。常用的异常检测方法主要有&#xff1a;统计方法、信息度量方法、谱映射方法、聚类方法、近邻方法和分类方法等。 …

VMware CentOS7 Linux 网络配置

本文主要描述VMware虚拟机的网络配置。 如上所示&#xff0c;在CentOS Linux虚拟机中设置网络连接使用桥接模式&#xff0c;该模式对接主机物理网络&#xff0c;直接由主机的物理网络的DHCP服务器动态分配IP地址&#xff0c;或者在CentOS Linux的操作系统的网络配置中设置静态的…