Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
zhhf96
C-Plus-Plus-TheAlgorithms
提交
327a4f57
C
C-Plus-Plus-TheAlgorithms
项目概览
zhhf96
/
C-Plus-Plus-TheAlgorithms
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
C-Plus-Plus-TheAlgorithms
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
327a4f57
编写于
8月 17, 2020
作者:
A
Ayaan Khan
提交者:
GitHub
8月 17, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1033 from fhlasek/dijkstra
fix: linter for dijkstra
上级
9adf7f46
c1961d7c
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
170 addition
and
42 deletion
+170
-42
graph/dijkstra.cpp
graph/dijkstra.cpp
+170
-42
未找到文件。
graph/dijkstra.cpp
浏览文件 @
327a4f57
#include <cstdio>
/**
* @file
* @brief [Graph Dijkstras Shortest Path Algorithm
* (Dijkstra's Shortest Path)]
* (https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)
*
* @author [Ayaan Khan](http://github.com/ayaankhan98)
*
* @details
* Dijkstra's Algorithm is used to find the shortest path from a source
* vertex to all other reachable vertex in the graph.
* The algorithm initially assumes all the nodes are unreachable from the
* given source vertex so we mark the distances of all vertices as INF
* (infinity) from source vertex (INF / infinity denotes unable to reach).
*
* in similar fashion with BFS we assume the distance of source vertex as 0
* and pushes the vertex in a priority queue with it's distance.
* we maintain the priority queue as a min heap so that we can get the
* minimum element at the top of heap
*
* Basically what we do in this algorithm is that we try to minimize the
* distances of all the reachable vertices from the current vertex, look
* at the code below to understand in better way.
*
*/
#include <cassert>
#include <iostream>
#include <limits>
#include <queue>
#include <utility>
#include <vector>
using
namespace
std
;
#define INF 10000010
vector
<
pair
<
int
,
int
>>
graph
[
5
*
100001
];
int
dis
[
5
*
100001
];
int
dij
(
vector
<
pair
<
int
,
int
>>
*
v
,
int
s
,
int
*
dis
)
{
priority_queue
<
pair
<
int
,
int
>
,
vector
<
pair
<
int
,
int
>>
,
greater
<
pair
<
int
,
int
>>>
#include <memory>
constexpr
int64_t
INF
=
std
::
numeric_limits
<
int64_t
>::
max
();
/**
* @namespace graph
* @brief Graph Algorithms
*/
namespace
graph
{
/**
* @brief Function that add edge between two nodes or vertices of graph
*
* @param u any node or vertex of graph
* @param v any node or vertex of graph
*/
void
addEdge
(
std
::
vector
<
std
::
vector
<
std
::
pair
<
int
,
int
>>>
*
adj
,
int
u
,
int
v
,
int
w
)
{
(
*
adj
)[
u
-
1
].
push_back
(
std
::
make_pair
(
v
-
1
,
w
));
// (*adj)[v - 1].push_back(std::make_pair(u - 1, w));
}
/**
* @brief Function runs the dijkstra algorithm for some source vertex and
* target vertex in the graph and returns the shortest distance of target
* from the source.
*
* @param adj input graph
* @param s source vertex
* @param t target vertex
*
* @return shortest distance if target is reachable from source else -1 in
* case if target is not reachable from source.
*/
int
dijkstra
(
std
::
vector
<
std
::
vector
<
std
::
pair
<
int
,
int
>>>
*
adj
,
int
s
,
int
t
)
{
/// n denotes the number of vertices in graph
int
n
=
adj
->
size
();
/// setting all the distances initially to INF
std
::
vector
<
int64_t
>
dist
(
n
,
INF
);
/// creating a min heap using priority queue
/// first element of pair contains the distance
/// second element of pair contains the vertex
std
::
priority_queue
<
std
::
pair
<
int
,
int
>
,
std
::
vector
<
std
::
pair
<
int
,
int
>>
,
std
::
greater
<
std
::
pair
<
int
,
int
>>>
pq
;
// source distance to zero.
pq
.
push
(
make_pair
(
0
,
s
));
dis
[
s
]
=
0
;
int
u
;
/// pushing the source vertex 's' with 0 distance in min heap
pq
.
push
(
std
::
make_pair
(
0
,
s
));
/// marking the distance of source as 0
dist
[
s
]
=
0
;
while
(
!
pq
.
empty
())
{
u
=
(
pq
.
top
()).
second
;
pq
.
pop
();
for
(
vector
<
pair
<
int
,
int
>>::
iterator
it
=
v
[
u
].
begin
();
it
!=
v
[
u
].
end
();
it
++
)
{
if
(
dis
[
u
]
+
it
->
first
<
dis
[
it
->
second
])
{
dis
[
it
->
second
]
=
dis
[
u
]
+
it
->
first
;
pq
.
push
(
make_pair
(
dis
[
it
->
second
],
it
->
second
));
}
/// second element of pair denotes the node / vertex
int
currentNode
=
pq
.
top
().
second
;
/// first element of pair denotes the distance
int
currentDist
=
pq
.
top
().
first
;
pq
.
pop
();
/// for all the reachable vertex from the currently exploring vertex
/// we will try to minimize the distance
for
(
std
::
pair
<
int
,
int
>
edge
:
(
*
adj
)[
currentNode
])
{
/// minimizing distances
if
(
currentDist
+
edge
.
second
<
dist
[
edge
.
first
])
{
dist
[
edge
.
first
]
=
currentDist
+
edge
.
second
;
pq
.
push
(
std
::
make_pair
(
dist
[
edge
.
first
],
edge
.
first
));
}
}
}
if
(
dist
[
t
]
!=
INF
)
{
return
dist
[
t
];
}
return
-
1
;
}
}
// namespace graph
/** Function to test the Algorithm */
void
tests
()
{
std
::
cout
<<
"Initiatinig Predefined Tests..."
<<
std
::
endl
;
std
::
cout
<<
"Initiating Test 1..."
<<
std
::
endl
;
std
::
vector
<
std
::
vector
<
std
::
pair
<
int
,
int
>>>
adj1
(
4
,
std
::
vector
<
std
::
pair
<
int
,
int
>>
());
graph
::
addEdge
(
&
adj1
,
1
,
2
,
1
);
graph
::
addEdge
(
&
adj1
,
4
,
1
,
2
);
graph
::
addEdge
(
&
adj1
,
2
,
3
,
2
);
graph
::
addEdge
(
&
adj1
,
1
,
3
,
5
);
int
s
=
1
,
t
=
3
;
assert
(
graph
::
dijkstra
(
&
adj1
,
s
-
1
,
t
-
1
)
==
3
);
std
::
cout
<<
"Test 1 Passed..."
<<
std
::
endl
;
s
=
4
,
t
=
3
;
std
::
cout
<<
"Initiating Test 2..."
<<
std
::
endl
;
assert
(
graph
::
dijkstra
(
&
adj1
,
s
-
1
,
t
-
1
)
==
5
);
std
::
cout
<<
"Test 2 Passed..."
<<
std
::
endl
;
std
::
vector
<
std
::
vector
<
std
::
pair
<
int
,
int
>>>
adj2
(
5
,
std
::
vector
<
std
::
pair
<
int
,
int
>>
());
graph
::
addEdge
(
&
adj2
,
1
,
2
,
4
);
graph
::
addEdge
(
&
adj2
,
1
,
3
,
2
);
graph
::
addEdge
(
&
adj2
,
2
,
3
,
2
);
graph
::
addEdge
(
&
adj2
,
3
,
2
,
1
);
graph
::
addEdge
(
&
adj2
,
2
,
4
,
2
);
graph
::
addEdge
(
&
adj2
,
3
,
5
,
4
);
graph
::
addEdge
(
&
adj2
,
5
,
4
,
1
);
graph
::
addEdge
(
&
adj2
,
2
,
5
,
3
);
graph
::
addEdge
(
&
adj2
,
3
,
4
,
4
);
s
=
1
,
t
=
5
;
std
::
cout
<<
"Initiating Test 3..."
<<
std
::
endl
;
assert
(
graph
::
dijkstra
(
&
adj2
,
s
-
1
,
t
-
1
)
==
6
);
std
::
cout
<<
"Test 3 Passed..."
<<
std
::
endl
;
std
::
cout
<<
"All Test Passed..."
<<
std
::
endl
<<
std
::
endl
;
}
/** Main function */
int
main
()
{
int
m
,
n
,
l
,
x
,
y
,
s
;
// n--> number of nodes , m --> number of edges
cin
>>
n
>>
m
;
for
(
int
i
=
0
;
i
<
m
;
i
++
)
{
// input edges.
scanf
(
"%d%d%d"
,
&
x
,
&
y
,
&
l
);
graph
[
x
].
push_back
(
make_pair
(
l
,
y
));
graph
[
y
].
push_back
(
make_pair
(
l
,
x
));
// comment this line for directed graph
}
// start node.
scanf
(
"%d"
,
&
s
);
// intialise all distances to infinity.
for
(
int
i
=
1
;
i
<=
n
;
i
++
)
dis
[
i
]
=
INF
;
dij
(
graph
,
s
,
dis
);
for
(
int
i
=
1
;
i
<=
n
;
i
++
)
if
(
dis
[
i
]
==
INF
)
cout
<<
"-1 "
;
else
cout
<<
dis
[
i
]
<<
" "
;
return
0
;
// running predefined tests
tests
();
int
vertices
=
int
(),
edges
=
int
();
std
::
cout
<<
"Enter the number of vertices : "
;
std
::
cin
>>
vertices
;
std
::
cout
<<
"Enter the number of edges : "
;
std
::
cin
>>
edges
;
std
::
vector
<
std
::
vector
<
std
::
pair
<
int
,
int
>>>
adj
(
vertices
,
std
::
vector
<
std
::
pair
<
int
,
int
>>
());
int
u
=
int
(),
v
=
int
(),
w
=
int
();
while
(
edges
--
)
{
std
::
cin
>>
u
>>
v
>>
w
;
graph
::
addEdge
(
&
adj
,
u
,
v
,
w
);
}
int
s
=
int
(),
t
=
int
();
std
::
cin
>>
s
>>
t
;
int
dist
=
graph
::
dijkstra
(
&
adj
,
s
-
1
,
t
-
1
);
if
(
dist
==
-
1
)
{
std
::
cout
<<
"Target not reachable from source"
<<
std
::
endl
;
}
else
{
std
::
cout
<<
"Shortest Path Distance : "
<<
dist
<<
std
::
endl
;
}
return
0
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录