【图算法】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算法解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树.该算法常用于路由算 ...
随机推荐
- VMWare中Linux虚拟机设置静态IP上网的设置方法
VMWare中Linux虚拟机设置静态IP上网的设置方法 标签: vmwareLinux虚拟机securecrt静态IP上网 2016-05-18 02:30 702人阅读 评论(0) 收藏 举报 ...
- EF5+MVC4系列(10) mvc的布局页面 _ViewStart.Cshtml
当客户端请求 /Product/Index的时候, 如果在视图的根目录下有 _ViewStart.Cshtml 就会先执行这个,再去执行 Product文件夹下的Index视图, 如果Product文 ...
- Linux 系统安装配置PHP服务(源码安装)
简介: PHP(外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于学习,使用广泛,主要 ...
- u3d静态函数
using UnityEngine; using System.Collections; public class Manager : MonoBehaviour { private static M ...
- Throwable vs Exception
Throwable中的Error是不需要程序处理的. Exception是需要处理的.
- Tomcat介绍 安装jdk 安装Tomcat
Tomcat介绍 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache.Sun和其他一些公司及个人共同开发而 ...
- css 设置背景图片铺满固定不动
#page{ position: relative; width: 100%; height: 100%; background-image:url(../img/bg.JPG); backgroun ...
- 深度学习 Deep Learning UFLDL 最新Tutorial 学习笔记 5:Softmax Regression
Softmax Regression Tutorial地址:http://ufldl.stanford.edu/tutorial/supervised/SoftmaxRegression/ 从本节開始 ...
- 使用vi时提示 write error in swap file
今天使用vi 命令时,提示write error in swap file 查了下原因,磁盘空间不够 df -h 使用 rm -rf 文件名 ,删除不用的 使用 echo "" & ...
- cp -rf 提示覆盖解决办法
cp覆盖时,无论加什么参数-f之类的还是提示是否覆盖,当文件比较少的时候还可以按Y确认,当很多文件的时候就不好说了 方法一:vi ~/.bashrc # .bashrc # User specific ...