【图算法】Dijkstra算法及变形
图示:

模版:
/*
Dijkstra计算单源最短路径,并记录路径 m个点,n条边,每条边上的权值非负,求起点st到终点et的最短路径 input:
n m st et
6 10 1 6
1 2 6
1 3 2
1 4 1
2 3 6
2 5 3
3 4 2
3 5 2
3 6 4
4 6 5
5 6 3 output:
6
1-->4-->6
*/ #include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std; #define INF 0xfffffff
#define MAXN 1010 int n,m; /*n:点数,m:边数*/
int st,et; /*st:起点,et:终点*/
int weight[MAXN][MAXN]; /*保存的是边权值*/
int dis[MAXN]; /*保存源点到任意点之间的最短路*/
int father[MAXN]; /*保存i点的父亲节点*/
int vis[MAXN]; /*记录哪些顶点已经求过最短路*/ void input()
{
scanf("%d%d%d%d",&n,&m,&st,&et);
int i,j;
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
weight[i][j]=INF;
weight[i][i]=;
}
int start,end,value;
for(i=;i<m;i++)
{
scanf("%d%d%d",&start,&end,&value);
if(weight[start][end]>value) //去重
weight[start][end]=weight[end][start]=value; //无向图
}
} void dijkstra()
{
int i,j;
memset(vis,,sizeof(vis));
memset(father,,sizeof(father)); //初始化dis数组
for(i=;i<=n;i++)
dis[i]=INF;
dis[st]=; //枚举n个点
for(i=;i<=n;i++)
{
int pos=-; //找到未加入集合的最短路的点
for(j=;j<=n;j++)
if(!vis[j]&&(pos==-||dis[j]<dis[pos]))
pos=j; //标记这个点已经走过
vis[pos]=; //更新dis
for(j=;j<=n;j++)
if(!vis[j]&&(dis[j]>dis[pos]+weight[pos][j]))
{
dis[j]=dis[pos]+weight[pos][j];
father[j]=pos;
}
}
} void output()
{
printf("%d\n",dis[et]);
int que[MAXN];
int cnt=;
int tmp=et;
while(father[tmp]!=)
{
que[cnt++]=tmp;
tmp=father[tmp];
}
int i;
printf("%d",st);
for(i=cnt-;i>=;i--)
printf("-->%d",que[i]);
printf("\n");
} int main()
{
input();
dijkstra();
output();
return ;
}
变形1:PAT 1030:http://www.patest.cn/contests/pat-a-practise/1030
题意:在原有计算weight的基础之上,再添加一个cost,最短路不唯一时,cost取最小。
分析:
#include<stack>
#include<stdio.h>
using namespace std; #define MAXN 502
#define INF 0xfffffff int n,m,s,d;
int weight[MAXN][MAXN];
int cost[MAXN][MAXN];
int dis[MAXN];
int cos[MAXN];
int pre[MAXN];
int vis[MAXN]; void init()
{
int i,j;
for(i=;i<n;i++)
{
for(j=;j<n;j++)
{
weight[i][j]=INF;
cost[i][j]=INF;
}
}
} void input()
{
int i,j; scanf("%d%d%d%d",&n,&m,&s,&d); init(); for(i=;i<m;i++)
{
int st,et,di,co;
scanf("%d%d%d%d",&st,&et,&di,&co);
if(di<weight[st][et])
{
weight[st][et]=weight[et][st]=di;
cost[st][et]=cost[et][st]=co;
}
else if(di==weight[st][et]&&co<cost[st][et])
{
cost[st][et]=cost[et][st]=co;
}
}
} void dijkstra()
{
int i,j; for(i=;i<n;i++)
{
vis[i]=;
pre[i]=-;
dis[i]=weight[s][i];
cos[i]=cost[s][i];
} vis[s]=; int mindist,pos; for(i=;i<n;i++)
{
mindist=INF;
for(j=;j<n;j++)
{
if(!vis[j]&&mindist>dis[j])
{
mindist=dis[j];
pos=j;
}
} vis[pos]=; if(pos==d)
{
return ;
} for(j=0;j<n;j++)
89 {
90 if(!vis[j]&&weight[pos][j]<INF)
91 {
92 if(dis[j]>dis[pos]+weight[pos][j])
93 {
94 dis[j]=dis[pos]+weight[pos][j];
95 cos[j]=cos[pos]+cost[pos][j];
96 pre[j]=pos;
97 }
98 else if(dis[j]==dis[pos]+weight[pos][j])
99 {
100 if(cos[j]>cos[pos]+cost[pos][j])
101 {
102 cos[j]=cos[pos]+cost[pos][j];
103 pre[j]=pos;
104 }
105 }
106 }
107 }
}
} void output()
{
stack<int>sta;
int p=d;
while(p!=-)
{
sta.push(p);
p=pre[p];
} printf("%d",s);
while(!sta.empty())
{
printf(" %d",sta.top());
sta.pop();
} printf(" %d %d\n",dis[d],cos[d]);
} int main()
{
input();
if(s==d)
{
printf("%d %d 0 0\n",s,d);
return ;
}
dijkstra();
output();
return ;
}
变形2:PAT 1018:http://pat.zju.edu.cn/contests/pat-a-practise/1018
【图算法】Dijkstra算法及变形的更多相关文章
- Dijkstra算法与堆(C++)
Dijkstra算法用于解决单源最短路径问题,通过逐个收录顶点来确保得到以收录顶点的路径长度为最短. 图片来自陈越姥姥的数据结构课程:https://mooc.study.163.com/l ...
- [图论]Dijkstra 算法小结
Dijkstra 算法小结 By Wine93 2013.11 1. Dijkstra 算法相关介绍 算法阐述:Dijkstra是解决单源最短路径的算法,它可以在O(n^2)内计算出源点(s)到图中 ...
- 单源最短路径-Dijkstra算法
1.算法标签 贪心 2.算法描述 具体的算法描述网上有好多,我觉得莫过于直接wiki,只说明一些我之前比较迷惑的. 对于Dijkstra算法,最重要的是维护以下几个数据结构: 顶点集合S : 表示已经 ...
- 一步一步深入理解Dijkstra算法
先简单介绍一下最短路径: 最短路径是啥?就是一个带边值的图中从某一个顶点到另外一个顶点的最短路径. 官方定义:对于内网图而言,最短路径是指两顶点之间经过的边上权值之和最小的路径. 并且我们称路径上的第 ...
- 最短路算法之Dijkstra算法通俗解释
Dijkstra算法 说明:求解从起点到任意点的最短距离,注意该算法应用于没有负边的图. 来,看图. 用邻接矩阵表示 int[][] m = { {0, 0, 0, 0, 0, 0}, {0, 0, ...
- 单源最短路径(1):Dijkstra 算法
一:背景 Dijkstra 算法(中文名:迪杰斯特拉算法)是由荷兰计算机科学家 Edsger Wybe Dijkstra 提出.该算法常用于路由算法或者作为其他图算法的一个子模块.举例来说,如果图中的 ...
- 最短路径问题---Dijkstra算法详解
侵删https://blog.csdn.net/qq_35644234/article/details/60870719 前言 Nobody can go back and start a new b ...
- 最短路径问题的Dijkstra算法
问题 最短路径问题的Dijkstra算法 是由荷兰计算机科学家艾兹赫尔·戴克斯特拉提出.迪科斯彻算法使用了广度优先搜索解决非负权有向图的单源最短路径问题,算法终于得到一个最短路径树> ...
- 最短路径-迪杰斯特拉(dijkstra)算法及优化详解
简介: dijkstra算法解决图论中源点到任意一点的最短路径. 算法思想: 算法特点: dijkstra算法解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树.该算法常用于路由算 ...
随机推荐
- e795. 获得和设置JSlider的值
// To create a slider, see e794 创建JSlider组件 // Get the current value int value = slider.getValue(); ...
- 用不上索引的SQL语句
下面介绍六种建立索引后不起作用的sql语句. 1.使用不等于操作符(<>, !=) SELECT * FROM dept WHERE staff_num <> 1000; × ...
- fence-agents kvm 实验
1, Method of installing fence-agents on linux: $ git clone https://github.com/ClusterLabs/fence-agen ...
- Chrome Adobe Flash Player 因过期而 阻止
百度搜索重装不管用 作者:胡中元链接:https://www.zhihu.com/question/32223811/answer/60456561来源:知乎著作权归作者所有.商业转载请联系作者获得授 ...
- Sql Server Snapshot和mysql MVCC
mysql 在一个事务A中插入一条数据 在B事务中查询到的还是以前的数据,可以select *from table,不被锁住 Sql Server 默认级别 读已提交 所以A事务在 X表插入数据, ...
- 新手windows安装nginx
windows安装nginx,下载地址:http://nginx.org/download/ 下载的时候,下载 .zip 后缀的压缩包,因为 .zip 的压缩包有nginx.exe 启动文件,其他没有 ...
- 杨涛老师MvcPager示例
杨涛老师插件地址:http://www.webdiyer.com/mvcpager 杨涛老师网站上示例写的很详细了,参考他的示例和帮助文档就可以运用的很好了,有经验的同学可以直接参考官方示例. 一.标 ...
- andoid-sdk 安装时出现 Stopping ADB server failed(code -1) 错
出错原因: cmd在path路径找不到adb命令,是因为adb.exe文件存在于android-sdk安装目录platform-tools/子目录下,要将这个路径配置到环境变量里面. 解决方案: 按照 ...
- node.js和socket.io实现im
im——Instant Messaging 即时通讯 基本技术原理 (1)通过IM服务器登陆或注销 (2)用户A通过列表找到B,用户B获得消息并与之交谈 (3)通过IM服务器指引建立与B单独的通讯通道 ...
- Android开发学习笔记-自定义组合控件的过程
自定义组合控件的过程 1.自定义一个View 一般来说,继承相对布局,或者线性布局 ViewGroup:2.实现父类的构造方法.一般来说,需要在构造方法里初始化自定义的布局文件:3.根据一些需要或者需 ...