forked from sunnyshahabuddin/Coding-Ninjas
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBidirectionalsearch.cpp
More file actions
197 lines (169 loc) · 4.55 KB
/
Bidirectionalsearch.cpp
File metadata and controls
197 lines (169 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <bits/stdc++.h>
using namespace std;
// class representing undirected graph
// using adjacency list
class Graph
{
//number of nodes in graph
int V;
// Adjacency list
list<int> *adj;
public:
Graph(int V);
int isIntersecting(bool *s_visited, bool *t_visited);
void addEdge(int u, int v);
void printPath(int *s_parent, int *t_parent, int s,
int t, int intersectNode);
void BFS(list<int> *queue, bool *visited, int *parent);
int biDirSearch(int s, int t);
};
Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
};
// Method for adding undirected edge
void Graph::addEdge(int u, int v)
{
this->adj[u].push_back(v);
this->adj[v].push_back(u);
};
// Method for Breadth First Search
void Graph::BFS(list<int> *queue, bool *visited,
int *parent)
{
int current = queue->front();
queue->pop_front();
list<int>::iterator i;
for (i=adj[current].begin();i != adj[current].end();i++)
{
// If adjacent vertex is not visited earlier
// mark it visited by assigning true value
if (!visited[*i])
{
// set current as parent of this vertex
parent[*i] = current;
// Mark this vertex visited
visited[*i] = true;
// Push to the end of queue
queue->push_back(*i);
}
}
};
// check for intersecting vertex
int Graph::isIntersecting(bool *s_visited, bool *t_visited)
{
int intersectNode = -1;
for(int i=0;i<V;i++)
{
// if a vertex is visited by both front
// and back BFS search return that node
// else return -1
if(s_visited[i] && t_visited[i])
return i;
}
return -1;
};
// Print the path from source to target
void Graph::printPath(int *s_parent, int *t_parent,
int s, int t, int intersectNode)
{
vector<int> path;
path.push_back(intersectNode);
int i = intersectNode;
while (i != s)
{
path.push_back(s_parent[i]);
i = s_parent[i];
}
reverse(path.begin(), path.end());
i = intersectNode;
while(i != t)
{
path.push_back(t_parent[i]);
i = t_parent[i];
}
vector<int>::iterator it;
cout<<"*****Path*****\n";
for(it = path.begin();it != path.end();it++)
cout<<*it<<" ";
cout<<"\n";
};
// Method for bidirectional searching
int Graph::biDirSearch(int s, int t)
{
// boolean array for BFS started from
// source and target(front and backward BFS)
// for keeping track on visited nodes
bool s_visited[V], t_visited[V];
// Keep track on parents of nodes
// for front and backward search
int s_parent[V], t_parent[V];
// queue for front and backward search
list<int> s_queue, t_queue;
int intersectNode = -1;
// necessary initialization
for(int i=0; i<V; i++)
{
s_visited[i] = false;
t_visited[i] = false;
}
s_queue.push_back(s);
s_visited[s] = true;
// parent of source is set to -1
s_parent[s]=-1;
t_queue.push_back(t);
t_visited[t] = true;
// parent of target is set to -1
t_parent[t] = -1;
while (!s_queue.empty() && !t_queue.empty())
{
// Do BFS from source and target vertices
BFS(&s_queue, s_visited, s_parent);
BFS(&t_queue, t_visited, t_parent);
// check for intersecting vertex
intersectNode = isIntersecting(s_visited, t_visited);
// If intersecting vertex is found
// that means there exist a path
if(intersectNode != -1)
{
cout << "Path exist between " << s << " and "
<< t << "\n";
cout << "Intersection at: " << intersectNode << "\n";
// print the path and exit the program
printPath(s_parent, t_parent, s, t, intersectNode);
exit(0);
}
}
return -1;
}
// Driver code
int main()
{
// no of vertices in graph
int n=15;
// source vertex
int s=0;
// target vertex
int t=14;
// create a graph given in above diagram
Graph g(n);
g.addEdge(0, 4);
g.addEdge(1, 4);
g.addEdge(2, 5);
g.addEdge(3, 5);
g.addEdge(4, 6);
g.addEdge(5, 6);
g.addEdge(6, 7);
g.addEdge(7, 8);
g.addEdge(8, 9);
g.addEdge(8, 10);
g.addEdge(9, 11);
g.addEdge(9, 12);
g.addEdge(10, 13);
g.addEdge(10, 14);
if (g.biDirSearch(s, t) == -1)
cout << "Path don't exist between "
<< s << " and " << t << "\n";
return 0;
}