Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
zhhf96
C-Plus-Plus-TheAlgorithms
提交
990e578a
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 搜索 >>
提交
990e578a
编写于
8月 16, 2020
作者:
F
Filip Hlásek
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'upstream/master'
上级
78ecea32
36f1d332
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
257 addition
and
122 deletion
+257
-122
geometry/jarvis_algorithm.cpp
geometry/jarvis_algorithm.cpp
+179
-0
graph/kosaraju.cpp
graph/kosaraju.cpp
+47
-40
graph/kruskal.cpp
graph/kruskal.cpp
+31
-82
未找到文件。
geometry/jarvis_algorithm.cpp
0 → 100644
浏览文件 @
990e578a
/**
* @file
* @brief Implementation of [Jarvis’s](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm.
*
* @details
* Given a set of points in the plane. the convex hull of the set
* is the smallest convex polygon that contains all the points of it.
*
* ### Algorithm
* The idea of Jarvis’s Algorithm is simple, we start from the leftmost point
* (or point with minimum x coordinate value) and we
* keep wrapping points in counterclockwise direction.
*
* The idea is to use orientation() here. Next point is selected as the
* point that beats all other points at counterclockwise orientation, i.e.,
* next point is q if for any other point r,
* we have “orientation(p, q, r) = counterclockwise”.
*
* For Example,
* If points = {{0, 3}, {2, 2}, {1, 1}, {2, 1},
{3, 0}, {0, 0}, {3, 3}};
*
* then the convex hull is
* (0, 3), (0, 0), (3, 0), (3, 3)
*
* @author [Rishabh Agarwal](https://github.com/rishabh-997)
*/
#include <vector>
#include <cassert>
#include <iostream>
/**
* @namespace geometry
* @brief Geometry algorithms
*/
namespace
geometry
{
/**
* @namespace jarvis
* @brief Functions for [Jarvis’s](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm
*/
namespace
jarvis
{
/**
* Structure defining the x and y co-ordinates of the given
* point in space
*/
struct
Point
{
int
x
,
y
;
};
/**
* Class which can be called from main and is globally available
* throughout the code
*/
class
Convexhull
{
std
::
vector
<
Point
>
points
;
int
size
;
public:
/**
* Constructor of given class
*
* @param pointList list of all points in the space
* @param n number of points in space
*/
explicit
Convexhull
(
const
std
::
vector
<
Point
>
&
pointList
)
{
points
=
pointList
;
size
=
points
.
size
();
}
/**
* Creates convex hull of a set of n points.
* There must be 3 points at least for the convex hull to exist
*
* @returns an vector array containing points in space
* which enclose all given points thus forming a hull
*/
std
::
vector
<
Point
>
getConvexHull
()
const
{
// Initialize Result
std
::
vector
<
Point
>
hull
;
// Find the leftmost point
int
leftmost_point
=
0
;
for
(
int
i
=
1
;
i
<
size
;
i
++
)
{
if
(
points
[
i
].
x
<
points
[
leftmost_point
].
x
)
{
leftmost_point
=
i
;
}
}
// Start from leftmost point, keep moving counterclockwise
// until reach the start point again. This loop runs O(h)
// times where h is number of points in result or output.
int
p
=
leftmost_point
,
q
=
0
;
do
{
// Add current point to result
hull
.
push_back
(
points
[
p
]);
// Search for a point 'q' such that orientation(p, x, q)
// is counterclockwise for all points 'x'. The idea
// is to keep track of last visited most counter clock-
// wise point in q. If any point 'i' is more counter clock-
// wise than q, then update q.
q
=
(
p
+
1
)
%
size
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
// If i is more counterclockwise than current q, then
// update q
if
(
orientation
(
points
[
p
],
points
[
i
],
points
[
q
])
==
2
)
{
q
=
i
;
}
}
// Now q is the most counterclockwise with respect to p
// Set p as q for next iteration, so that q is added to
// result 'hull'
p
=
q
;
}
while
(
p
!=
leftmost_point
);
// While we don't come to first point
return
hull
;
}
/**
* This function returns the geometric orientation for the three points
* in a space, ie, whether they are linear ir clockwise or
* anti-clockwise
* @param p first point selected
* @param q adjacent point for q
* @param r adjacent point for q
*
* @returns 0 -> Linear
* @returns 1 -> Clock Wise
* @returns 2 -> Anti Clock Wise
*/
static
int
orientation
(
const
Point
&
p
,
const
Point
&
q
,
const
Point
&
r
)
{
int
val
=
(
q
.
y
-
p
.
y
)
*
(
r
.
x
-
q
.
x
)
-
(
q
.
x
-
p
.
x
)
*
(
r
.
y
-
q
.
y
);
if
(
val
==
0
)
{
return
0
;
}
return
(
val
>
0
)
?
1
:
2
;
}
};
}
// namespace jarvis
}
// namespace geometry
/**
* Test function
* @returns void
*/
static
void
test
()
{
std
::
vector
<
geometry
::
jarvis
::
Point
>
points
=
{{
0
,
3
},
{
2
,
2
},
{
1
,
1
},
{
2
,
1
},
{
3
,
0
},
{
0
,
0
},
{
3
,
3
}
};
geometry
::
jarvis
::
Convexhull
hull
(
points
);
std
::
vector
<
geometry
::
jarvis
::
Point
>
actualPoint
;
actualPoint
=
hull
.
getConvexHull
();
std
::
vector
<
geometry
::
jarvis
::
Point
>
expectedPoint
=
{{
0
,
3
},
{
0
,
0
},
{
3
,
0
},
{
3
,
3
}};
for
(
int
i
=
0
;
i
<
expectedPoint
.
size
();
i
++
)
{
assert
(
actualPoint
[
i
].
x
==
expectedPoint
[
i
].
x
);
assert
(
actualPoint
[
i
].
y
==
expectedPoint
[
i
].
y
);
}
std
::
cout
<<
"Test implementations passed!
\n
"
;
}
/** Driver Code */
int
main
()
{
test
();
return
0
;
}
graph/kosaraju.cpp
浏览文件 @
990e578a
...
...
@@ -4,77 +4,84 @@
#include <iostream>
#include <vector>
#include <stack>
using
namespace
std
;
/**
* Iterative function/method to print graph:
* @param a
[] : array of vectors (2D)
* @param V
:
vertices
* @param a
adjacency list representation of the graph
* @param V
number of
vertices
* @return void
**/
void
print
(
vector
<
int
>
a
[]
,
int
V
)
{
void
print
(
const
std
::
vector
<
std
::
vector
<
int
>
>
&
a
,
int
V
)
{
for
(
int
i
=
0
;
i
<
V
;
i
++
)
{
if
(
!
a
[
i
].
empty
())
cout
<<
"i="
<<
i
<<
"-->"
;
for
(
int
j
=
0
;
j
<
a
[
i
].
size
();
j
++
)
cout
<<
a
[
i
][
j
]
<<
" "
;
if
(
!
a
[
i
].
empty
())
cout
<<
endl
;
if
(
!
a
[
i
].
empty
())
{
std
::
cout
<<
"i="
<<
i
<<
"-->"
;
}
for
(
int
j
:
a
[
i
])
{
std
::
cout
<<
j
<<
" "
;
}
if
(
!
a
[
i
].
empty
())
{
std
::
cout
<<
std
::
endl
;
}
}
}
/**
* //Recursive function/method to push vertices into stack passed as parameter:
* @param v
:
vertices
* @param
&st :
stack passed by reference
* @param vis
[] :
array to keep track of visited nodes (boolean type)
* @param adj
[] : array of vectors to represent
graph
* @param v vertices
* @param
st
stack passed by reference
* @param vis array to keep track of visited nodes (boolean type)
* @param adj
adjacency list representation of the
graph
* @return void
**/
void
push_vertex
(
int
v
,
st
ack
<
int
>
&
st
,
bool
vis
[],
vector
<
int
>
adj
[]
)
{
vis
[
v
]
=
true
;
void
push_vertex
(
int
v
,
st
d
::
stack
<
int
>
*
st
,
std
::
vector
<
bool
>
*
vis
,
const
std
::
vector
<
std
::
vector
<
int
>
>
&
adj
)
{
(
*
vis
)
[
v
]
=
true
;
for
(
auto
i
=
adj
[
v
].
begin
();
i
!=
adj
[
v
].
end
();
i
++
)
{
if
(
vis
[
*
i
]
==
false
)
if
(
(
*
vis
)[
*
i
]
==
false
)
{
push_vertex
(
*
i
,
st
,
vis
,
adj
);
}
}
st
.
push
(
v
);
st
->
push
(
v
);
}
/**
* //Recursive function/method to implement depth first traversal(dfs):
* @param v
:
vertices
* @param vis
[] :
array to keep track of visited nodes (boolean type)
* @param grev
[] :
graph with reversed edges
* @param v vertices
* @param vis array to keep track of visited nodes (boolean type)
* @param grev graph with reversed edges
* @return void
**/
void
dfs
(
int
v
,
bool
vis
[],
vector
<
int
>
grev
[]
)
{
vis
[
v
]
=
true
;
void
dfs
(
int
v
,
std
::
vector
<
bool
>
*
vis
,
const
std
::
vector
<
std
::
vector
<
int
>
>
&
grev
)
{
(
*
vis
)
[
v
]
=
true
;
// cout<<v<<" ";
for
(
auto
i
=
grev
[
v
].
begin
();
i
!=
grev
[
v
].
end
();
i
++
)
{
if
(
vis
[
*
i
]
==
false
)
if
(
(
*
vis
)[
*
i
]
==
false
)
{
dfs
(
*
i
,
vis
,
grev
);
}
}
}
// function/method to implement Kosaraju's Algorithm:
/**
* Info about the method
* @param V
:
vertices in graph
* @param adj
[] :
array of vectors that represent a graph (adjacency list/array)
* @param V vertices in graph
* @param adj array of vectors that represent a graph (adjacency list/array)
* @return int ( 0, 1, 2..and so on, only unsigned values as either there can be
no SCCs i.e. none(0) or there will be x no. of SCCs (x>0)) i.e. it returns the
count of (number of) strongly connected components (SCCs) in the graph.
(variable 'count_scc' within function)
**/
int
kosaraju
(
int
V
,
vector
<
int
>
adj
[]
)
{
bool
vis
[
V
]
=
{}
;
stack
<
int
>
st
;
int
kosaraju
(
int
V
,
const
std
::
vector
<
std
::
vector
<
int
>
>
&
adj
)
{
std
::
vector
<
bool
>
vis
(
V
,
false
)
;
st
d
::
st
ack
<
int
>
st
;
for
(
int
v
=
0
;
v
<
V
;
v
++
)
{
if
(
vis
[
v
]
==
false
)
push_vertex
(
v
,
st
,
vis
,
adj
);
if
(
vis
[
v
]
==
false
)
{
push_vertex
(
v
,
&
st
,
&
vis
,
adj
);
}
}
// making new graph (grev) with reverse edges as in adj[]:
vector
<
int
>
grev
[
V
]
;
std
::
vector
<
std
::
vector
<
int
>
>
grev
(
V
)
;
for
(
int
i
=
0
;
i
<
V
+
1
;
i
++
)
{
for
(
auto
j
=
adj
[
i
].
begin
();
j
!=
adj
[
i
].
end
();
j
++
)
{
grev
[
*
j
].
push_back
(
i
);
...
...
@@ -89,7 +96,7 @@ int kosaraju(int V, vector<int> adj[]) {
int
t
=
st
.
top
();
st
.
pop
();
if
(
vis
[
t
]
==
false
)
{
dfs
(
t
,
vis
,
grev
);
dfs
(
t
,
&
vis
,
grev
);
count_scc
++
;
}
}
...
...
@@ -101,21 +108,21 @@ int kosaraju(int V, vector<int> adj[]) {
// All critical/corner cases have been taken care of.
// Input your required values: (not hardcoded)
int
main
()
{
int
t
;
cin
>>
t
;
int
t
=
0
;
std
::
cin
>>
t
;
while
(
t
--
)
{
int
a
,
b
;
// a->number of nodes, b->directed edges.
cin
>>
a
>>
b
;
int
m
,
n
;
vector
<
int
>
adj
[
a
+
1
]
;
int
a
=
0
,
b
=
0
;
// a->number of nodes, b->directed edges.
std
::
cin
>>
a
>>
b
;
int
m
=
0
,
n
=
0
;
std
::
vector
<
std
::
vector
<
int
>
>
adj
(
a
+
1
)
;
for
(
int
i
=
0
;
i
<
b
;
i
++
)
// take total b inputs of 2 vertices each
// required to form an edge.
{
cin
>>
m
>>
n
;
// take input m,n denoting edge from m->n.
std
::
cin
>>
m
>>
n
;
// take input m,n denoting edge from m->n.
adj
[
m
].
push_back
(
n
);
}
// pass number of nodes and adjacency array as parameters to function:
cout
<<
kosaraju
(
a
,
adj
)
<<
endl
;
std
::
cout
<<
kosaraju
(
a
,
adj
)
<<
std
::
endl
;
}
return
0
;
}
graph/kruskal.cpp
浏览文件 @
990e578a
#include <iostream>
#include <vector>
#include <algorithm>
#include <array>
//#include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision;
const
int
mx
=
1e6
+
5
;
const
long
int
inf
=
2e9
;
typedef
long
long
ll
;
#define rep(i, n) for (i = 0; i < n; i++)
#define repp(i, a, b) for (i = a; i <= b; i++)
#define pii pair<int, int>
#define vpii vector<pii>
#define vi vector<int>
#define vll vector<ll>
#define r(x) scanf("%d", &x)
#define rs(s) scanf("%s", s)
#define gc getchar_unlocked
#define pc putchar_unlocked
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define endl "\n"
#define fast \
ios_base::sync_with_stdio(false); \
cin.tie(NULL); \
cout.tie(NULL);
using
namespace
std
;
void
in
(
int
&
x
)
{
register
int
c
=
gc
();
x
=
0
;
int
neg
=
0
;
for
(;
((
c
<
48
||
c
>
57
)
&&
c
!=
'-'
);
c
=
gc
())
;
if
(
c
==
'-'
)
{
neg
=
1
;
c
=
gc
();
}
for
(;
c
>
47
&&
c
<
58
;
c
=
gc
())
{
x
=
(
x
<<
1
)
+
(
x
<<
3
)
+
c
-
48
;
}
if
(
neg
)
x
=
-
x
;
}
void
out
(
int
n
)
{
int
N
=
n
,
rev
,
count
=
0
;
rev
=
N
;
if
(
N
==
0
)
{
pc
(
'0'
);
return
;
}
while
((
rev
%
10
)
==
0
)
{
count
++
;
rev
/=
10
;
}
rev
=
0
;
while
(
N
!=
0
)
{
rev
=
(
rev
<<
3
)
+
(
rev
<<
1
)
+
N
%
10
;
N
/=
10
;
}
while
(
rev
!=
0
)
{
pc
(
rev
%
10
+
'0'
);
rev
/=
10
;
}
while
(
count
--
)
pc
(
'0'
);
}
ll
parent
[
mx
],
arr
[
mx
],
node
,
edge
;
vector
<
pair
<
ll
,
pair
<
ll
,
ll
>>>
v
;
using
ll
=
int64_t
;
std
::
array
<
ll
,
mx
>
parent
;
ll
node
,
edge
;
std
::
vector
<
std
::
pair
<
ll
,
std
::
pair
<
ll
,
ll
>>>
edges
;
void
initial
()
{
int
i
;
rep
(
i
,
node
+
edge
)
parent
[
i
]
=
i
;
for
(
int
i
=
0
;
i
<
node
+
edge
;
++
i
)
{
parent
[
i
]
=
i
;
}
}
int
root
(
int
i
)
{
while
(
parent
[
i
]
!=
i
)
{
parent
[
i
]
=
parent
[
parent
[
i
]];
...
...
@@ -75,41 +23,42 @@ int root(int i) {
}
return
i
;
}
void
join
(
int
x
,
int
y
)
{
int
root_x
=
root
(
x
);
// Disjoint set union by rank
int
root_y
=
root
(
y
);
parent
[
root_x
]
=
root_y
;
}
ll
kruskal
()
{
ll
mincost
=
0
,
i
,
x
,
y
;
rep
(
i
,
edge
)
{
x
=
v
[
i
].
second
.
first
;
y
=
v
[
i
].
second
.
second
;
ll
mincost
=
0
;
for
(
int
i
=
0
;
i
<
edge
;
++
i
)
{
ll
x
=
edges
[
i
].
second
.
first
;
ll
y
=
edges
[
i
].
second
.
second
;
if
(
root
(
x
)
!=
root
(
y
))
{
mincost
+=
v
[
i
].
first
;
mincost
+=
edges
[
i
].
first
;
join
(
x
,
y
);
}
}
return
mincost
;
}
int
main
()
{
fast
;
while
(
1
)
{
int
i
,
j
,
from
,
to
,
cost
,
totalcost
=
0
;
cin
>>
node
>>
edge
;
// Enter the nodes and edges
if
(
node
==
0
&&
edge
==
0
)
while
(
true
)
{
int
from
=
0
,
to
=
0
,
cost
=
0
,
totalcost
=
0
;
std
::
cin
>>
node
>>
edge
;
// Enter the nodes and edges
if
(
node
==
0
&&
edge
==
0
)
{
break
;
// Enter 0 0 to break out
}
initial
();
// Initialise the parent array
rep
(
i
,
edge
)
{
cin
>>
from
>>
to
>>
cost
;
v
.
pb
(
mp
(
cost
,
mp
(
from
,
to
)));
for
(
int
i
=
0
;
i
<
edge
;
++
i
)
{
std
::
cin
>>
from
>>
to
>>
cost
;
edges
.
emplace_back
(
make_pair
(
cost
,
std
::
make_pair
(
from
,
to
)));
totalcost
+=
cost
;
}
sort
(
v
.
begin
(),
v
.
end
());
// rep(i,v.size())
// cout<<v[i].first<<" ";
cout
<<
kruskal
()
<<
endl
;
v
.
clear
();
sort
(
edges
.
begin
(),
edges
.
end
());
std
::
cout
<<
kruskal
()
<<
std
::
endl
;
edges
.
clear
();
}
return
0
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录