mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-04-04 19:20:17 +08:00
feat: Add ncr mod p code (#1325)
* feat: Add ncr mod p code (#1323) * Update math/ncr_modulo_p.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Added all functions inside a class + added more asserts * updating DIRECTORY.md * clang-format and clang-tidy fixes forf6df24a5* Replace int64_t to uint64_t + add namespace + detailed documentation * clang-format and clang-tidy fixes fore09a0579* Add extra namespace + add const& in function arguments * clang-format and clang-tidy fixes for8111f881* Update ncr_modulo_p.cpp * clang-format and clang-tidy fixes for2ad2f721* Update math/ncr_modulo_p.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update math/ncr_modulo_p.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update math/ncr_modulo_p.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes for5b69ba5c* updating DIRECTORY.md * clang-format and clang-tidy fixes fora8401d4bCo-authored-by: David Leal <halfpacho@gmail.com> Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
@@ -48,136 +48,138 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* \namespace graph
|
||||
* \brief Graph algorithms
|
||||
*/
|
||||
namespace graph{
|
||||
/* Class Graph definition */
|
||||
template<typename T>
|
||||
class Graph{
|
||||
namespace graph {
|
||||
/* Class Graph definition */
|
||||
template <typename T>
|
||||
class Graph {
|
||||
/**
|
||||
* adjacency_list maps every vertex to the list of its neighbours in the order
|
||||
* in which they are added.
|
||||
*/
|
||||
std::map<T,std::list<T> > adjacency_list;
|
||||
public:
|
||||
Graph(){};
|
||||
void add_edge(T u,T v, bool bidir=true){
|
||||
* adjacency_list maps every vertex to the list of its neighbours in the
|
||||
* order in which they are added.
|
||||
*/
|
||||
std::map<T, std::list<T> > adjacency_list;
|
||||
|
||||
public:
|
||||
Graph() = default;
|
||||
;
|
||||
void add_edge(T u, T v, bool bidir = true) {
|
||||
/**
|
||||
* add_edge(u,v,bidir) is used to add an edge between node u and node v
|
||||
* by default , bidir is made true , i.e graph is bidirectional .
|
||||
* It means if edge(u,v) is added then u-->v and v-->u both edges exist.
|
||||
*
|
||||
* to make the graph unidirectional pass the third parameter of add_edge as
|
||||
* false which will
|
||||
*/
|
||||
adjacency_list[u].push_back(v); // u-->v edge added
|
||||
if(bidir==true){
|
||||
// if graph is bidirectional
|
||||
adjacency_list[v].push_back(u); // v-->u edge added
|
||||
* add_edge(u,v,bidir) is used to add an edge between node u and
|
||||
* node v by default , bidir is made true , i.e graph is
|
||||
* bidirectional . It means if edge(u,v) is added then u-->v and
|
||||
* v-->u both edges exist.
|
||||
*
|
||||
* to make the graph unidirectional pass the third parameter of
|
||||
* add_edge as false which will
|
||||
*/
|
||||
adjacency_list[u].push_back(v); // u-->v edge added
|
||||
if (bidir == true) {
|
||||
// if graph is bidirectional
|
||||
adjacency_list[v].push_back(u); // v-->u edge added
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* this function performs the breadth first search on graph and return a
|
||||
* mapping which maps the nodes to a boolean value representing whether the
|
||||
* node was traversed or not.
|
||||
*/
|
||||
std::map<T,bool> breadth_first_search(T src){
|
||||
/// mapping to keep track of all visited nodes
|
||||
std::map<T,bool> visited;
|
||||
}
|
||||
|
||||
/**
|
||||
* this function performs the breadth first search on graph and return a
|
||||
* mapping which maps the nodes to a boolean value representing whether the
|
||||
* node was traversed or not.
|
||||
*/
|
||||
std::map<T, bool> breadth_first_search(T src) {
|
||||
/// mapping to keep track of all visited nodes
|
||||
std::map<T, bool> visited;
|
||||
/// initialise every possible vertex to map to false
|
||||
/// initially none of the vertices are unvisited
|
||||
for(auto const &adjlist: adjacency_list){
|
||||
visited[adjlist.first]=false;
|
||||
for(auto const &node:adjacency_list[adjlist.first]){
|
||||
visited[node]=false;
|
||||
}
|
||||
for (auto const &adjlist : adjacency_list) {
|
||||
visited[adjlist.first] = false;
|
||||
for (auto const &node : adjacency_list[adjlist.first]) {
|
||||
visited[node] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// queue to store the nodes which are yet to be traversed
|
||||
std::queue<T> tracker;
|
||||
|
||||
/// push the source vertex to queue to begin traversing
|
||||
|
||||
/// push the source vertex to queue to begin traversing
|
||||
tracker.push(src);
|
||||
///mark the source vertex as visited
|
||||
visited[src]=true;
|
||||
while(!tracker.empty()){
|
||||
/// traverse the graph till no connected vertex are left
|
||||
/// extract a node from queue for further traversal
|
||||
T node = tracker.front();
|
||||
/// remove the node from the queue
|
||||
tracker.pop();
|
||||
for(T const &neighbour : adjacency_list[node]){
|
||||
/// check every vertex connected to the node which are still unvisited
|
||||
if(!visited[neighbour]){
|
||||
/// if the neighbour is unvisited , push it into the queue
|
||||
tracker.push(neighbour);
|
||||
/// mark the neighbour as visited
|
||||
visited[neighbour]=true;
|
||||
/// mark the source vertex as visited
|
||||
visited[src] = true;
|
||||
while (!tracker.empty()) {
|
||||
/// traverse the graph till no connected vertex are left
|
||||
/// extract a node from queue for further traversal
|
||||
T node = tracker.front();
|
||||
/// remove the node from the queue
|
||||
tracker.pop();
|
||||
for (T const &neighbour : adjacency_list[node]) {
|
||||
/// check every vertex connected to the node which are still
|
||||
/// unvisited
|
||||
if (!visited[neighbour]) {
|
||||
/// if the neighbour is unvisited , push it into the queue
|
||||
tracker.push(neighbour);
|
||||
/// mark the neighbour as visited
|
||||
visited[neighbour] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return visited;
|
||||
}
|
||||
};
|
||||
/* Class definition ends */
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
/* Class definition ends */
|
||||
} // namespace graph
|
||||
|
||||
/** Test function */
|
||||
static void tests() {
|
||||
/// Test 1 Begin
|
||||
graph::Graph<int> g;
|
||||
std::map<int,bool> correct_result;
|
||||
g.add_edge(0,1);
|
||||
g.add_edge(1,2);
|
||||
g.add_edge(2,3);
|
||||
correct_result[0]=true;
|
||||
correct_result[1]=true;
|
||||
correct_result[2]=true;
|
||||
correct_result[3]=true;
|
||||
std::map<int, bool> correct_result;
|
||||
g.add_edge(0, 1);
|
||||
g.add_edge(1, 2);
|
||||
g.add_edge(2, 3);
|
||||
correct_result[0] = true;
|
||||
correct_result[1] = true;
|
||||
correct_result[2] = true;
|
||||
correct_result[3] = true;
|
||||
|
||||
std::map<int,bool> returned_result = g.breadth_first_search(2);
|
||||
std::map<int, bool> returned_result = g.breadth_first_search(2);
|
||||
|
||||
assert(returned_result==correct_result);
|
||||
assert(returned_result == correct_result);
|
||||
std::cout << "Test 1 Passed..." << std::endl;
|
||||
|
||||
/// Test 2 Begin
|
||||
returned_result = g.breadth_first_search(0);
|
||||
|
||||
assert(returned_result==correct_result);
|
||||
|
||||
assert(returned_result == correct_result);
|
||||
std::cout << "Test 2 Passed..." << std::endl;
|
||||
|
||||
/// Test 3 Begins
|
||||
graph::Graph<std::string> g2;
|
||||
|
||||
g2.add_edge("Gorakhpur","Lucknow",false);
|
||||
g2.add_edge("Gorakhpur","Kanpur",false);
|
||||
g2.add_edge("Lucknow","Agra",false);
|
||||
g2.add_edge("Kanpur","Agra",false);
|
||||
g2.add_edge("Lucknow","Prayagraj",false);
|
||||
g2.add_edge("Agra","Noida",false);
|
||||
g2.add_edge("Gorakhpur", "Lucknow", false);
|
||||
g2.add_edge("Gorakhpur", "Kanpur", false);
|
||||
g2.add_edge("Lucknow", "Agra", false);
|
||||
g2.add_edge("Kanpur", "Agra", false);
|
||||
g2.add_edge("Lucknow", "Prayagraj", false);
|
||||
g2.add_edge("Agra", "Noida", false);
|
||||
|
||||
std::map<std::string,bool> correct_res;
|
||||
std::map<std::string,bool> returned_res=g2.breadth_first_search("Kanpur");
|
||||
correct_res["Gorakhpur"]=false;
|
||||
correct_res["Lucknow"]=false;
|
||||
correct_res["Kanpur"]=true;
|
||||
correct_res["Agra"]=true;
|
||||
correct_res["Prayagraj"]=false;
|
||||
correct_res["Noida"]=true;
|
||||
assert(correct_res==returned_res);
|
||||
std::map<std::string, bool> correct_res;
|
||||
std::map<std::string, bool> returned_res =
|
||||
g2.breadth_first_search("Kanpur");
|
||||
correct_res["Gorakhpur"] = false;
|
||||
correct_res["Lucknow"] = false;
|
||||
correct_res["Kanpur"] = true;
|
||||
correct_res["Agra"] = true;
|
||||
correct_res["Prayagraj"] = false;
|
||||
correct_res["Noida"] = true;
|
||||
assert(correct_res == returned_res);
|
||||
std::cout << "Test 3 Passed..." << std::endl;
|
||||
|
||||
}
|
||||
|
||||
/** Main function */
|
||||
@@ -194,7 +196,7 @@ int main() {
|
||||
while (edges--) {
|
||||
int u = 0, v = 0;
|
||||
std::cin >> u >> v;
|
||||
g.add_edge(u,v);
|
||||
g.add_edge(u, v);
|
||||
}
|
||||
|
||||
g.breadth_first_search(0);
|
||||
|
||||
Reference in New Issue
Block a user