-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0785-Is_Graph_Bipartite.cpp
140 lines (130 loc) · 4.06 KB
/
0785-Is_Graph_Bipartite.cpp
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
/*******************************************************************************
* 0785-Is_Graph_Bipartite.cpp
* Billy.Ljm
* 19 May 2023
*
* =======
* Problem
* =======
* https://leetcode.com/problems/is-graph-bipartite/
*
* There is an undirected graph with n nodes, where each node is numbered
* between 0 and n - 1. You are given a 2D array graph, where graph[u] is an
* array of nodes that node u is adjacent to. More formally, for each v in
* graph[u], there is an undirected edge between node u and node v. The graph
* has the following properties:
*
* - There are no self-edges (graph[u] does not contain u).
* - There are no parallel edges (graph[u] does not contain duplicate values).
* - If v is in graph[u], then u is in graph[v] (the graph is undirected).
* - The graph may not be connected, meaning there may be two nodes u and v such
* that there is no path between them.
*
* A graph is bipartite if the nodes can be partitioned into two independent
* sets A and B such that every edge in the graph connects a node in set A and a
* node in set B.
*
* Return true if and only if it is bipartite.
*
* ===========
* My Approach
* ===========
* We can start from any node, label it A, traverse to all its neighbours, then
* label them B and so on. If there is any contradiction in the labelling, then
* the graph is not bipartite. If all nodes have been traversed and there is no
* contradiction, then the graph is bipartite.
*
* This has a time complexity of O(e) and space complexity of O(v), where e is
* the number of edges and v is the number of vertices.
******************************************************************************/
#include <iostream>
#include <vector>
/**
* Solution
*/
class Solution {
private:
/**
* Recursively label a node and traverse its neighbours
*
* @param node node to label
* @param label label for node
* @param graph graph[i] lists neighbours of node i
* @param visited visited[i] is true if node i has been visited
* @param labelled labelled[i] is the label for node i
*
* @return false if there is contradiction in labels, true if no problem
*/
bool recurse(int node, bool label, std::vector<std::vector<int>>& graph,
std::vector<bool>& visited, std::vector<bool>& labelled) {
// check labels of visited node
if (visited[node]) {
return labelled[node] == label;
}
// label unvisited nodes and recurse
else {
// label current node
visited[node] = true;
labelled[node] = label;
// recursively label all neighbours
for (int i : graph[node]) {
if (not recurse(i, !label, graph, visited, labelled)) {
return false; // reecho any contradiction
}
}
// all neighbours labelled w/ no issues
return true;
}
}
public:
/**
* Checks if a graph is bipartite
*
* @param graph graph[i] lists neighbours of node i
*
* @return true if graph is bipartite, false if its not bipartite
*/
bool isBipartite(std::vector<std::vector<int>>& graph) {
// remember if node is visited and if which bipartite its labelled as
std::vector<bool> visited (graph.size(), false);
std::vector<bool> labelled(graph.size());
// traverse all nodes if unvisited
for (int i = 0; i < graph.size(); i++) {
if (not visited[i]) {
if (not recurse(i, true, graph, visited, labelled)) {
return false; // contradiction found, return false
}
}
}
// all node traversed w/o contradiction
return true;
}
};
/**
* << operator for vectors
*/
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
os << "[";
for (int i = 0; i < v.size(); i++) {
os << v[i] << ",";
}
os << "\b]";
return os;
}
/**
* Test cases
*/
int main(void) {
Solution sol;
std::vector<std::vector<int>> graph;
// test case 1
graph = { {1, 2, 3}, {0, 2}, {0, 1, 3}, {0, 2} };
std::cout << std::boolalpha << "isBipartite(" << graph << ") = " <<
sol.isBipartite(graph) << std::endl;
// test case 2
graph = { {1, 3}, {0, 2}, {1, 3}, {0, 2} };
std::cout << std::boolalpha << "isBipartite(" << graph << ") = " <<
sol.isBipartite(graph) << std::endl;
return 0;
}