diff --git a/GraphX.py b/GraphX.py new file mode 100644 index 0000000..a975280 --- /dev/null +++ b/GraphX.py @@ -0,0 +1,171 @@ +//COPY THE BLACKBOX, there is no need to change anything in it. +//Check the main function at bottom for USAGE + +//****************BLACKBOX START***************** +//START COPYING FROM HERE + +typedef int ll; + +class Hash { + private: + map,int>hash_table; + public: + Hash () {} + int hash(int x){ + return hash({x,0,0}); + } + int hash(tuplex){ + return hash({get<0>(x),get<1>(x),0}); + } + int hash(tuplex){ + if(hash_table.find(x)!=hash_table.end()) + return hash_table[x]; + int new_hash = hash_table.size(); + hash_table[x]=new_hash; + return new_hash; + } +}; + +class Graph { + + bool is_directed; + + public: + vector>>adj; + int n,N=5000000; + Hash h; + + Graph(int n_, bool is_directed_ = true){ + n=n_; is_directed = is_directed_; + adj.resize(N,vector>()); + } + + int hash(int u, int v){ + return h.hash({u,v}); + } + int hash(int u, int v, int k){ + return h.hash({u,v,k}); + } + + void add_edge(int uR, int vR, ll c=0){ + int u=h.hash(uR), v=h.hash(vR); + add_edge_internal(u,v,c); + } + void add_edge(tuple uR, tuple vR, ll c=0){ + int u=h.hash(uR), v=h.hash(vR); + add_edge_internal(u,v,c); + } + void add_edge(tuple uR, tuple vR, ll c=0){ + int u=h.hash(uR), v=h.hash(vR); + add_edge_internal(u,v,c); + } + + + private : + + void add_edge_internal(int u, int v, ll c=0){ + add_edge_weighted_undirected(u,v,c); + if(!is_directed) + add_edge_weighted_undirected(v,u,c); + } + void add_edge_weighted_undirected(int u, int v, ll c) { + pairp = make_pair(v,c); + adj[u].push_back(p); + } + +}; + +class BFS { + vectormin_dist_from_source; + vector visited; + Graph *g; + + public: + BFS(Graph *g_) { + g = g_; + clear(); + } + + void clear() { + min_dist_from_source.clear(); + min_dist_from_source.resize(g->N,-1); + visited.clear(); + visited.resize(g->N, false); + } + + + void run(int sourceR) { + int source = (g->h).hash(sourceR); + run_internal(source); + } + void run(tuple sourceR) { + int source = (g->h).hash(sourceR); + run_internal(source); + } + void run(tuple sourceR) { + int source = (g->h).hash(sourceR); + run_internal(source); + } + + + int min_dist(int targetR){ + int target = (g->h).hash(targetR); + return min_dist_internal(target); + } + int min_dist(tuple targetR){ + int target = (g->h).hash(targetR); + return min_dist_internal(target); + } + int min_dist(tuple targetR){ + int target = (g->h).hash(targetR); + return min_dist_internal(target); + } + + bool is_visited(int targetR){ + int target = (g->h).hash(targetR); + return is_visited_internal(target); + } + bool is_visited(tuple targetR){ + int target = (g->h).hash(targetR); + return is_visited_internal(target); + } + bool is_visited(tuple targetR){ + int target = (g->h).hash(targetR); + return is_visited_internal(target); + } + + private: + void run_internal(int source) { + queue q; + q.push(source); + + visited[source] = true; + min_dist_from_source[source] = 0; + + while(!q.empty()) { + int cur_node = q.front(); + for (unsigned int i = 0; i < (g->adj[cur_node]).size(); ++i) { + int adj_node = (g->adj[cur_node])[i].first; + if (visited[adj_node] == false) { + visited[adj_node] = true; + min_dist_from_source[adj_node] = min_dist_from_source[cur_node] + 1; + q.push(adj_node); + } + } + q.pop(); + } + + return; + } + + int min_dist_internal(int target){ + return min_dist_from_source[target]; + } + + bool is_visited_internal(int target){ + return visited[target]; + } + +}; +//END COPYING HERE +//********************BLACKBOX END******************