Advance Graphs-1424
Advance Graphs-1424
Advance Graphs-1424
Connected Components
Explanation:
1
In the above graph there is a path from every vertex to every other vertex,
therefore this is a connected graph. In this case we say that the graph has only one
connected component.
There may be graphs which do not satisfy the above conditions and are called
disconnected graphs. However in such cases, there may still be several components
which are connected within themselves. For example,
2
In the above figure vertices 1, 2, 3, 4 form a connected component. Another
connected component is formed by vertices 5, 6 and vertex 7 itself is a connected
component.
To find the connected components in an undirected graph, we can use either DFS
or BFS for this task.
Let’s take a look at the algorithm that uses DFS to solve this problem:
We have already taken a look at how DFS and BFS work in the previous lectures
along with their codes.
3
Permutations Swap
Problem Statement:
Kevin has a permutation P of N integers 1, 2, ..., N, but he doesn't like it. Kevin
wants to get a permutation Q.
He also believes that there are M good pairs of integers (ai, bi). Kevin can perform
following operation with his permutation:
Help him and tell if Kevin can obtain permutation Q using such operations.
Explanation:
We are also given some pairs of numbers {(1, 2), (2, 3), (2, 4)}. Each number in a
pair represents that the two indexes or positions can be switched with each other.
4
This problem can be approached using the concept of hasPath. This basically
means that if we are given a pair (1, 2), then these can be considered as the vertices
in a graph and since they are a pair that means there exists an edge between them.
SImilarly there exists an edge between (2, 3) and (2, 4). So the corresponding graph
for the above problem can be represented as the following figure:
5
Now, even if we can’t directly perform some operations we can indirectly do them.
For example, if we have to swap indexes 1 and 3 then they are not in our given
pairs but what we could do is first perform swap on index 1 and 2 and then
perform swap on index 2 and 3. So overall there needs to exist a path between the
indexes ( vertices) for swap operation.
6
Strongly Connected Components
Kosaraju’s Algorithm
7
1. Do a DFS on the original graph: Do a DFS on the original graph, keeping
track of the finish times of each node. This can be done using a stack, when a
DFS finishes put the source vertex on the stack. This way the node with the
highest finishing time will be on top of the stack.
2. Reverse the original graph: Reverse the graph using an adjacency list.
3. Do DFS again: Do DFS on the reversed graph, with the source vertex as the
vertex on top of the stack. When DFS finishes, all nodes visited will form one
Strongly Connected Component. If any more nodes remain unvisited, this
means there are more Strongly Connected Components, so pop vertices
from top of the stack until a valid unvisited node is found. This will have the
highest finishing time of all currently unvisited nodes. This step is repeated
until all nodes are visited.
Let us take a look at an example to see the working of the above algorithm:
8
1. After applying DFS on this graph starting from node 0, and keeping track of
the finishing time of each node with the help of the stack, our stack becomes
9
3. Pop every element out of the stack. If it’s not visited, apply DFS on it and that
will give us the SCC.
Step 1. We pop an element at the top that is node 0. We apply DFS(0) , hence it
will visit node 1,2,3. Now we mark them as visited and this forms our first group.
Step 2. We pop the second element which is 1 but since it is visited we skip this.
Step 3. We pop the third element which is 4. Since it is not visited we apply
DFS(4). Now it will visit only 4 as there are no adjacent nodes. Hence 4 is a
separate group.
10
Step 4.We pop the fourth element which is 5. Since it is not visited we apply
DFS(5). It will visit 5,6,7. Hence 5,6,7 will form a separate group.
Step 5. We pop the fifth element which is 6 , since it is already visited we skip.
Now we pop the sixth element which is 7 , since it is already visited we skip it.
Similarly we skip seventh and eight elements which are 2 and 3 as they are
already visited.
Now , the stack is empty and our algorithm stops.
The nodes printed are:
0321
4
576
Code:
#include <iostream>
#include <vector>
#include <stack>
#include <unordered_set>
using namespace std;
11
visited.insert(start);
component->insert(start);
for (int i = 0; i < edges[start].size(); i++) {
int adjacent = edges[start][i];
if (visited.count(adjacent) == 0) {
dfs2(edges, adjacent, component, visited);
}
}
}
int main() {
int n;
cin >> n;
vector<int>* edges = new vector<int>[n];
vector<int>* edgesT = new vector<int>[n];
12
int m;
cin >> m;
for (int i = 0; i < m; i++) {
int j, k;
cin >> j >> k;
edges[j - 1].push_back(k - 1);
edgesT[k - 1].push_back(j - 1);
}
unordered_set<unordered_set<int>*>* components = getSCC(edges,
edgesT, n);
unordered_set<unordered_set<int>*>::iterator it =
components->begin();
while (it != components->end()) {
unordered_set<int>* component = *it;
unordered_set<int>::iterator it2 = component->begin();
while (it2 != component->end()) {
cout << *it2 + 1<< " ";
it2++;
}
cout << endl;
delete component;
it++;
}
delete components;
delete [] edges;
delete [] edgesT;
}
Bipartite Graphs
13
A bipartite graph is a graph whose vertices can be divided into two disjoint sets so
that every edge connects two vertices from different sets (i.e. there are no edges
which connect vertices from the same set). These sets are usually called sides.
In the above graph, the nodes are marked with either Red Color or Blue Color. Now,
these colors can be represented as Sets. So according to the definition of Bipartite
14
graphs there should be no edge between two red vertices or two blue vertices. So the
above graph is clearly not Bipartite.
Now, let's take a look at another example
The above graph has no edge between the vertices of the same color (set), therefore, it
is a bipartite graph.
15
2. Now, we are going to pick a starting vertex and place it in any of the sets ( let’s
say set1 ) and we are going to push it in the queue.
3. Now, pop the vertex from the queue and place its neighbours in set2 and the
queue.
4. On popping the next vertex from the queue, we have to check whether any of its
neighbours is present in set2 or not.
5. If the 4th statement returns true, then the graph is not bipartite.
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
16
}
}
}
return true;
}
int main() {
while (true) {
int n;
cin >> n;
if (n == 0)
break;
vector<int>* edges = new vector<int>[n];
int m;
cin >> m;
for (int i = 0; i < m; i++) {
int j, k;
cin >> j >> k;
edges[j].push_back(k);
edges[k].push_back(j);
}
bool ans = bipartite(edges, n);
delete [] edges;
if (ans) {
cout << "BICOLORABLE." << endl;
} else {
cout << "NOT BICOLORABLE." << endl;
}
}
}
17