图论(1):单源最短路的建图方式

news2025/1/11 8:49:19

一、单源最短路算法

最短路算法_yan__kai_的博客-CSDN博客

二、例题

1.acwing1129

 题意解读:走过一条路存在花费c,求最小费用即求最短路。无向图

直接背模板:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef pair<int,int> PII;
const int N =3000,M= 6200 * 2 + 10;

int h[N],e[M],ne[M],w[M],idx;
int n,m;
int start,ed;
bool st[N];
int dist[N];

void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}

int dijkstra()
{
    memset(dist,0x3f,sizeof dist);
    priority_queue<PII,vector<PII>,greater<PII> > heap;

    dist[start]=0;    
    heap.push({0,start});
    while(heap.size())
    {
        auto t=heap.top();
        heap.pop();

        int ver=t.second;
        if(st[ver]) continue;
        st[ver]=true;

        for(int i=h[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[ver]+w[i])
            {
                dist[j]=dist[ver]+w[i];
                heap.push({dist[j],j});
            }
        }

    }
    return dist[ed];

}

int main()
{
    cin>>n>>m>>start>>ed;
    memset(h,-1,sizeof h);
    for(int i=0;i<m;i++)
    {
        int a,b,w;
        scanf("%d%d%d",&a,&b,&w);
        add(a,b,w);
        add(b,a,w);
    }
    int t=dijkstra();
    printf("%d",t);
}

作者:yankai
链接:https://www.acwing.com/activity/content/code/content/4279854/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2.acwing1128

 题意:从起点到其他各点的送信时间实际上仍然是最短路算法,,答案要求我们输出最短时间,实际上就是起点到其它各点的最长时间(最远的点收到通信即代表送信完成)

直接背板子,本着复习的态度,这里不再用dijkstra,而是用floyd算法

复习:floyd算法需要初始化自己到自己的距离为0,初始化其它距离为无穷

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int N =110,INF=0x3f3f3f3f;

int n,m;
int d[N][N];

int main()
{
    cin>>n>>m;
    memset(d,0x3f,sizeof d);
    for(int i=1;i<=n;i++) d[i][i]=0;
    for(int i=0;i<m;i++)
    {
        int a,b,w;
        cin>>a>>b>>w;
        d[a][b]=d[b][a]=min(d[a][b],w);
    }

    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
            }
    int res=0;
    for(int i=1;i<=n;i++)
        if(d[1][i]>=INF)
        {
            res=-1;
            break;
        }
        else res=max(res,d[1][i]);
    cout<<res;
    return 0;
}

作者:yankai
链接:https://www.acwing.com/activity/content/code/content/4279898/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3.acwing1127

 点数800,边数1500。求一次最短路mlogn,枚举所有点放黄油,复杂度mnlogn,本题数据量很小可以接受直接暴力枚举放黄油的点。

直接模板求最短路,然后算距离即可。本着复习的原则,本题用spfa算法

spfa算法认为,只有被更新过的点,才能更新后继的结点。即如果一个节点没有被更新过,那么再拿这个节点去更新其他结点是没有效果的。所以使用队列,存储被更新的结点,st表示这个节点是否在队列当中,防止队列里面加了相同的节点。     

        注意:st数组的使用、判断无解的条件。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

const int N =810,M=3000,INF=0x3f3f3f3f;

int n,p,m;
int dist[N];
bool st[N];
int h[N],e[M],ne[M],w[M],idx;
int id[N];

void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}

int spfa(int start)
{
    memset(dist,0x3f,sizeof dist);
    memset(st,false,sizeof false);
    dist[start]=0;
    queue<int> q;
    q.push(start);
    st[start]=true;

    while(q.size())
    {
        int t=q.front();
        q.pop();

        st[t]=false;

        for(int i=h[t];~i;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[t]+w[i])
            {
                dist[j]=dist[t]+w[i];
                st[j]=true;
                q.push(j);
            }
        }
    }

    int res=0;
    for(int i=0;i<n;i++)
    {
        int j=id[i];
        if(dist[j]==INF) return INF;
        res+=dist[j];
    }
    return res;
}




int main()
{
    cin>>n>>p>>m;
    memset(h,-1,sizeof h);
    for(int i=0;i<n;i++) cin>>id[i];
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c),add(b,a,c);
    }

    int res=INF;
    for(int i=1;i<=p;i++) res=min(res,spfa(i));

    cout<<res;

}

作者:yankai
链接:https://www.acwing.com/activity/content/code/content/4279946/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4.acwing1126

 建图:人 作为点,A为起点B为终点,边长是扣除手续费,dist为保留原费用的百分比,即初始化A的dist为1,走向下一个点(假设扣除z%的手续费,即dist(a)*g,,g=(100-c)/100)

那么走到最后答案就是100/dist(b)

目标是让dist(b)尽量大,则跑最长路即可

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

const int N =2010;

int n,m,S,T;
double g[N][N];
double dist[N];
bool st[N];

void dijkstra()
{
    dist[S]=1;
    for(int i=1;i<=n;i++)
    {
        int t=-1;
        for(int j=1;j<=n;j++)
            if(!st[j]&&(t==-1||dist[t]<dist[j]))
                t=j;
        st[t]=true;
        for(int j=1;j<=n;j++)
            dist[j]=max(dist[j],dist[t]*g[t][j]);
    }

}

int main()
{
    cin>>n>>m;
    while(m--)
    {
        int a,b,c;
        cin>>a>>b>>c;
        double z=(100.0-c)/100;
        g[a][b]=g[b][a]=max(g[a][b],z);
    }
    cin>>S>>T;
    dijkstra();
    printf("%.8lf",100/dist[T]);
}

作者:yankai
链接:https://www.acwing.com/activity/content/code/content/4280167/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

5.acwing920

 答案要求输出最少换乘次数。问题根本在如何建图使得求解方便上。

假设我们乘上了j号站,则我们下一步可选择到包含j号站的所有线路,的在j号站之后的所有站下车换乘。

据此考虑,我们把j号点与这条线路上之后的所有点加一条边,长度为1。这样就能使得建出来的图能够使用最短路算法求解。

因为长度为1,因此我们使用bfs算法即可求解最短路。

直接bfs求解的实际上是“坐车的次数”,答案应该是不换乘——0 和坐车的次数-1.

注意坐车的次数可以是0,因此答案表达式为max(0,dist[end]-1)

#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<queue>
using namespace std;

const int N =510;

int m,n;
int dist[N];
bool g[N][N];
bool st[N];
int stop[N];

void bfs()
{
    queue<int> q;
    memset(dist,0x3f,sizeof dist);
    q.push(1);
    dist[1]=0;
    while(q.size())
    {
        int t=q.front();
        q.pop();
        for(int i=1;i<=n;i++)
            if(g[t][i]&&dist[i]>dist[t]+1)
            {
                dist[i]=dist[t]+1;
                q.push(i);
            }
    }
}


int main()
{
    cin>>m>>n;
    string line;
    getline(cin,line);
    while(m--)
    {
        getline(cin,line);
        stringstream ssin(line);
        int cnt=0,p;
        while(ssin>>p) stop[cnt++]=p;
        for(int j=0;j<cnt;j++)//每个站点 与之后的 所有站点建一条单向边
            for(int k=j+1;k<cnt;k++)
                g[stop[j]][stop[k]]=true;
    } 
    bfs();//01bfs求最短路
    if(dist[n]==0x3f3f3f3f) puts("NO");
    else cout<<max(dist[n]-1,0);
    return 0;

}

作者:yankai
链接:https://www.acwing.com/activity/content/code/content/4327369/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

6.acwing903

 

 题意:N=100,可以用邻接矩阵建图;物品--点,边--某个物品可以的替代品。边的意义即为,从这个替代品出发,花费代价w可以到达该物品,这样就可以用最短路。

与地位低的交易了,地位高度的不会和他交易:只能选择一个起点出发。

求解方法:我们总要选择一个起点出发,如何选择交给算法解决最好。因此我们可以设立一个虚拟原点,将它和所有物品连线,边的代价就是交易的代价。这样我们直接从虚拟源点开始跑最短路即可求得答案dist(1)。

等级差距超过了M则不能“间接交易”:因此我们需要限制间接交易的区间,区间必须要包括level1,并且为了防止遗漏最短路,必须要枚举所有包括了level1的区间。跑dijkstra受到等级区间限制,需要传入两个参数:等级最低限制和最高限制。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int N =110 ,INF=0x3f3f3f3f;

int level[N];
int w[N][N];
bool st[N];
int dist[N];
int m,n;

int dijkstra(int down,int up)
{
    memset(dist,0x3f,sizeof dist);
    memset(st,false,sizeof st);

    dist[0]=0;
    for(int i=1;i<=n+1;i++)//n+1个点
    {
        int t=-1;
        for(int j=0;j<=n;j++)//注意是从0号点开始循环
            if((t==-1||dist[t]>dist[j])&&!st[j])
                t=j;
        st[t]=true;
        for(int j=1;j<=n;j++)
            if(level[j]>=down&&level[j]<=up)
                dist[j]=min(dist[j],dist[t]+w[t][j]);
    }
    return dist[1];
}


int main()
{
    cin>>m>>n;
    memset(w,0x3f,sizeof w);
    for(int i=0;i<=n;i++) w[i][i]=0;

    for(int i=1;i<=n;i++)
    {
        int price,cnt;
        cin>>price>>level[i]>>cnt;
        w[0][i]=min(price,w[0][i]);//虚拟原点 代表直接购买这件物品
        while(cnt--)
        {
            int id,cost;
            cin>>id>>cost;
            w[id][i]=min(cost,w[id][i]);
        }
    }

    int res=INF;
    for(int i=level[1]-m;i<=level[1];i++)  res=min(res,dijkstra(i,i+m));
    cout<<res;
    return 0;
}

作者:yankai
链接:https://www.acwing.com/activity/content/code/content/4327877/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

 

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

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

相关文章

环形轨道运料电动葫芦无线控制系统的组成与功能

一&#xff0e;关于环形轨道运料电动葫芦的控制 目前电动葫芦的控制部分都是由PLC完成的&#xff0c;每个电葫芦内都有一台PLC&#xff0c;主站PLC一般设置在地面控制机柜内。由于电葫芦是在半空中移动工作的&#xff0c;与地面PLC的通讯问题一直是电葫芦设备运行中棘手的问题…

虚拟人,会成为品牌下一次逆势的解药吗?

如果说2021年是虚拟偶像的崛起元年&#xff0c;那2022可以称得上是爆发期了&#xff0c;一方面&#xff0c;定位国风、时尚博主、模特、歌手的虚拟偶像数量激增&#xff0c;被冠以“首位”、“行业第一”等称号的新面孔轮番出道&#xff1b;其次&#xff0c;虚拟人与品牌的商业…

不同Excel多列对比记录新增、修改、删除和无变化的行,并生成对比报告

执行【Exce数据对比.exe】&#xff0c;打开界面如图选择要对比的Excel文件和被对比的Excel文件&#xff0c;输入要对比Sheet页的需要&#xff08;注意&#xff0c;Sheet需要从0开始&#xff09;输入主键列和被对比的列。主键列和被对比列均为二维列表&#xff0c;列的索引从0开…

七、HashSet底层详解

文章目录特点结论源码解读构造器添加元素小结说明练习(重要*掌握)思考特点 无序、无索引 不可重复(地址)&#xff0c;可存一个null 不可用索引取出 存放和取出顺序不一定一样 但每次取出的顺序是一样的 遍历只能迭代器和增强for 底层其实是HashMap 结论 源码解读 构造…

Spring AOP源码:配置文件解析过程

前言 本篇文章主要讲解AOP配置中的几个通知类的解析过程&#xff0c;为后续对目标类进行代理做准备&#xff1b;在前面的Spring IOC篇我们讲解了自定义配置的解析&#xff0c;AOP配置的解析过程也是其自定义注解的过程&#xff0c;如果不熟悉自定义解析过程可以看之前的文章Sp…

CVPR2017|Deep Feature Flow for Video Recognition论文复现(pytorch版)

&#x1f3c6;引言&#xff1a;深度卷积神经网络在图像识别任务中取得了巨大的成功。然而&#xff0c;将最先进的图像识别网络转移到视频上并非易事&#xff0c;因为每帧评估速度太慢且负担不起。我们提出了一种快速准确的视频识别框架——深度特征流DFF。它只在稀疏关键帧上运…

数据通信基础 - 调制技术

文章目录1 概述2 调制技术2.1 分类2.2 N 相调制3 网工软考真题1 概述 #mermaid-svg-ZTF6pPysJlmUes01 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ZTF6pPysJlmUes01 .error-icon{fill:#552222;}#mermaid-svg-ZTF…

谷歌用量子处理器发现:光子能在混沌中保持稳健的束缚态

一圈超导量子比特可以容纳微波光子的“束缚态”&#xff0c;其中光子往往聚集在相邻的量子比特位点上。图片来源&#xff1a;Google Quantum AI 使用量子处理器&#xff0c;研究人员可以使微波光子具有异常的“粘性”。在诱使它们聚集成束缚态后&#xff0c;他们发现这些光子簇…

谷歌 Chrome 浏览器弹窗境外广告的解决方法

谷歌的 Chrome 浏览器是我非常喜欢的一款的浏览器&#xff0c;用了它之后就不想再用其它浏览器。可是不知道从什么时候开始&#xff0c;Chrome 浏览器居然时不时地在右下角弹出广告&#xff0c;仔细一看&#xff0c;还是境外的 VPN 广告&#xff0c;如下图。有弹出过几次了&…

如何通过创建 SSH key 来进行Git 代码管理

1.检查你的电脑是否已经有SSH Key&#xff1f; 运行如下命令查看&#xff1a; $ cd ~/.ssh $ ls如果存在id_rsa.pub或 id_dsa.pub 文件&#xff0c;说明你的电脑已经有 SSH Key &#xff0c;可以直接拿来用&#xff0c;如果没有的话需要创建。 2.创建SSH Key 配置全局的nam…

zookeeper入门篇

文章目录前言介绍安装与启动配置说明节点节点类型PERSISTENT&#xff08;持久化节点&#xff09;PERSISTENT_SEQUENTIAL&#xff08;持久化顺序节点&#xff09;EPHEMERAL&#xff08;临时节点&#xff09;EPHEMERAL_SEQUENTIAL&#xff08;临时顺序节点&#xff09;Container&…

用Java实现简单的图书管理系统(Java系列7)

目录 前言&#xff1a; 1.基础框架的搭建 1.1图书 1.1.1书 1.1.2书架 1.2用户 1.2.1抽象类 1.2.2普通用户 1.2.3管理员 1.3操作 1.3.1新增图书 1.3.2借阅图书 1.3.3删除图书 1.3.4退出图书 1.3.5查找图书 1.3.6归还图书 1.3.7显示图书 2.具体内容的实现 2.1Ma…

<flutter>跨平台开发新手入坑指南 dart dio pubspec.yaml json_annotation 打包 小坑指南

1.资源文件和依赖三方包&#xff08;pubspec.yaml&#xff09;&#xff1a; pubspec.yaml文件可以说是和安卓的gradle文件差不多&#xff0c;它用来描述版本号、sdk、依赖等的。 在资源导入方面同安卓不一样的是&#xff0c;flutter需要在pubspec.yaml中声名&#xff0c;不然…

【PCB专题】Allegro元件库路径设置方法

正常Layout拉线前,需要将原理图导出的网表导入到Allegro里,Allegro就会自动将元件导入。如果库路径没有设置或都软件找不到器件,将会非常的卡顿,并且报Completed with warnings/errors。如下图所示: 在弹出的错误报告View of file:netrev.lst中会提示很多器件找不到封装。…

js知识点

js有预解析阶段&#xff0c;变量声明提升只提升定义&#xff0c;不提升值 console.log(a);//undefined var a10; 基本数据类型 Number、String、Boolean、Undefined和Null 复杂数据类型 Object、Array、Function、RegExp、Date、Map、Set等 使用typeof运算符可以检测值或…

刷爆力扣之验证回文串 II

刷爆力扣之验证回文串 II HELLO&#xff0c;各位看官大大好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 今天阿呆继续记录下力扣刷题过程&#xff0c;收录在专栏算法中 &#x1f61c;&#x1f61c;&#x1f61c; 该专栏按照不同类别标签进行刷题&#xff…

第六章 作业【数据库原理】

第六章 作业【数据库原理】前言推荐第六章 作业第6章第1题&#xff08;简答题&#xff09;第6章第2题&#xff08;简答题&#xff09;第6章第3题&#xff08;设计题&#xff09;第6章第4题&#xff08;设计题&#xff09;最后前言 2022-12-27 16:05:55 以下内容源自数据库原理…

最大连续子序列的和问题(算法)

问题描述 给定一个有n&#xff08;n≥1&#xff09;个整数的序列&#xff0c;要求求出其中最大连续子序列的和。 蛮力法 暴力枚举 /*** 时间复杂度&#xff1a;O(n^3)* param arr 序列[数组]* param n 数组大小* return int */ int maxSubSum1(int arr[], int n) {int thi…

美团餐饮SaaS基于StarRocks构建商家数据中台的探索

作者&#xff1a;何启航&#xff0c;美团餐饮SaaS数据专家&#xff08;文章整理自作者在 StarRocks Summit Asia 2022 的分享&#xff09; 随着社会经济的发展&#xff0c;餐饮连锁商家越来越大&#xff0c;“万店时代”来临。对于美团餐饮 SaaS 来说&#xff0c;传统的 OLTP …