备战蓝桥杯---图论之最短路dijkstra算法

目录

先分个类吧:

1.对于有向无环图,我们直接拓扑排序,和AOE网类似,把取max改成min即可。

2.边权全部相等,直接BFS即可

3.单源点最短路

从一个点出发,到达其他顶点的最短路长度。

Dijkstra算法:用于一个节点到所有其他节点的最短路。(要求:不存在负权边,可以用于无向图)


先分个类吧:

1.对于有向无环图,我们直接拓扑排序,和AOE网类似,把取max改成min即可。

2.边权全部相等,直接BFS即可

3.单源点最短路

从一个点出发,到达其他顶点的最短路长度。

基本操作:松弛:d[u]+w<d[v],于是距离更改。

Dijkstra算法:用于一个节点到所有其他节点的最短路。(要求:不存在负权边,可以用于无向图)

具体过程:

1.开始之前,认为所有点都未计算,dis[]全部赋为极大值。

2.源点的dis[]=0;

3。计算与源点相邻的所有点的dis=map[s][v];

4.在还未算出最短路点的dis中选出最小一个点u,显然,因为不存在负权边,它的最短路就是dis.

5.对于与u相连的所有点v若dis[u]+map[u][v]比当前的dis小就松弛更新。

6.重复上述4,5操作。

正确性证明:

其实就是每一次贪心,显然,从源点开始的第一步得到的最短的路肯定就是最短路(到它的其他路肯定比它长)。

当我们把除源点外第一个确定的加入后,我们再用它去更新一下它连的点。

然后,我们选其中最小的点,它就是确定的。因为,要走到它,要么从那些没有确定最小路的点出发到它(因为这点是最小的点+无负权边,因此这样的点距离肯定更大),要么从已经确定的点上拓展出来,又因为他们不断地更新松弛(每一个确定最小路的点加入后,我们再用它去更新一下它连的点),所以我们可以保证在已经确定地点到最小的点的路径是最优的。因此,我们保证最小的点它就是确定的。

下面放一道模板题:

下面是AC代码(注意,无向边建图edge要2倍):

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
struct node{
    int zhi;
    int dian;
    int next;
}edge[20010];
int dis[1010],head[1010],cnt,n,m1,s,t,x,y,v;
bool vis[1010];
struct ty{
    int dian,dis1;
    bool operator<(const ty &a) const{
        return dis1>a.dis1;
    }
};
void merge(int x,int y,int v){
    edge[++cnt].zhi=v;
    edge[cnt].dian=y;
    edge[cnt].next=head[x];
    head[x]=cnt;
}
priority_queue<ty> q;
int dij(int s,int t){
    q.push({s,0});
    while(!q.empty()){
        ty ck=q.top();
          q.pop();
        if(vis[ck.dian]==1) continue;
        vis[ck.dian]=1;
        for(int i=head[ck.dian];i!=-1;i=edge[i].next){
            int i1=edge[i].dian;
            if(vis[i1]==1) continue;
            if(dis[i1]>dis[ck.dian]+edge[i].zhi){
                dis[i1]=dis[ck.dian]+edge[i].zhi;
                 q.push({i1,dis[i1]});
            }
        }
    }
    if(dis[t]>=0x3f3f3f3f) return -1;
    else return dis[t];
}
int main(){
    cin>>n>>m1>>s>>t;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=m1;i++){
        scanf("%d%d%d",&x,&y,&v);
        merge(x,y,v);
        merge(y,x,v);
    }
    memset(dis,0x3f,sizeof(dis));
    dis[s]=0;
    cout<<dij(s,t);
}
相关推荐
坚持就完事了10 小时前
Java算法:递归
算法
senijusene10 小时前
数据结构与算法:完全二叉树和非完全二叉数的各种详细操作以及哈希表的简单应用
数据结构·算法·链表
水饺编程10 小时前
第4章,[标签 Win32] :文本的格式化,等待完善
c语言·c++·windows·visual studio
似霰10 小时前
Android 平台智能指针使用与分析
android·c++
季明洵10 小时前
反转字符串、反转字符串II、反转字符串中的单词
java·数据结构·算法·leetcode·字符串
2401_8414956410 小时前
【Python高级编程】近似串匹配
python·算法·动态规划·字符串·数组·时间复杂度·空间复杂度
lingggggaaaa10 小时前
安全工具篇&魔改二开&CheckSum8算法&Beacon密钥&Stager流量&生成机制
学习·算法·安全·web安全·网络安全·免杀对抗
阿猿收手吧!10 小时前
【C++】实现自旋锁:三种高效实现与实战指南
服务器·网络·c++
Python+JAVA+大数据10 小时前
SQL玩出算法竞赛高度!郑凌云数独算法:递归CTE+位运算DFS回溯全解析
数据库·sql·算法·搜索引擎·深度优先·dfs
MicroTech202510 小时前
量子主成分分析(QPCA):微算法科技(NASDAQ :MLGO)重构图像降维与特征提取的技术
科技·算法·重构