diff --git a/05- May/18- Minimum Number of Vertices to Reach All Nodes/18- Minimum Number of Vertices to Reach All Nodes (Lama Salah).cpp b/05- May/18- Minimum Number of Vertices to Reach All Nodes/18- Minimum Number of Vertices to Reach All Nodes (Lama Salah).cpp new file mode 100644 index 000000000..55b1ed045 --- /dev/null +++ b/05- May/18- Minimum Number of Vertices to Reach All Nodes/18- Minimum Number of Vertices to Reach All Nodes (Lama Salah).cpp @@ -0,0 +1,42 @@ +// Author : Lama Salah + +class Solution { +public: + int par[100005]; // Initialize 'par' array of size (1e5 + 5) to keep track of the parent of each node. + + // Find function to get and update the root parent of a node. + int find(int node){ + // If the node is its own parent, return the node. + // Otherwise, recursively find the parent and update the parent of the current node. + return par[node] == node ? node : par[node] = find(par[node]); + } + + vector findSmallestSetOfVertices(int n, vector>& edges) { + vector ans; // Vector to store the smallest set of vertices. + set unique; // Set to store unique root parents. + + // Step 1: Initialize parent array for each node. + for (int i = 0; i < n; i++) { + par[i] = i; + } + + // Step 2: Iterate through the 'edges' vector and for each edge, + // set the parent of the second node (e[1]) as the first node (e[0]). + for (auto& e : edges) { + par[e[1]] = e[0]; + } + + // Step 3: Find the root parent of each node and insert into the set. + for (int i = 0; i < n; i++) { + unique.insert(find(i)); + } + + // Step 4: Append the root parents to the result vector. + for (auto& i : unique) { + ans.emplace_back(i); + } + + // Return the minimum number of vertices to reach all nodes. + return ans; + } +}; \ No newline at end of file diff --git a/05- May/18- Minimum Number of Vertices to Reach All Nodes/18- Minimum Number of Vertices to Reach All Nodes (Noura Algohary).cpp b/05- May/18- Minimum Number of Vertices to Reach All Nodes/18- Minimum Number of Vertices to Reach All Nodes (Noura Algohary).cpp new file mode 100644 index 000000000..a515f1b72 --- /dev/null +++ b/05- May/18- Minimum Number of Vertices to Reach All Nodes/18- Minimum Number of Vertices to Reach All Nodes (Noura Algohary).cpp @@ -0,0 +1,25 @@ +// Author: Noura Algohary +class Solution { +public: + vector findSmallestSetOfVertices(int n, vector>& edges) { + // a vector to show the nodes that have incoming edges + vectorreached(n, 0); + // nodes with zero incoming edges + vectorsolution; + + for(auto edge:edges) + { + // count how many times the node is reached + reached[edge[1]]++; + } + + for(int node = 0;node List[int]: + # a list to show the nodes that have incoming edges + reached = [0 for i in range(n)] + # nodes with zero incoming edges + solution = [] + + for edge in edges: + # count how many times the node is reached + reached[edge[1]]+=1 + + for node in range(n): + # is the node have a count of 0 incoming edges + if reached[node] ==0: + solution.append(node) + + return solution \ No newline at end of file diff --git a/05- May/18- Minimum Number of Vertices to Reach All Nodes/18- Minimum Number of Vertices to Reach All Nodes (Osama Ayman).java b/05- May/18- Minimum Number of Vertices to Reach All Nodes/18- Minimum Number of Vertices to Reach All Nodes (Osama Ayman).java new file mode 100644 index 000000000..23f340cb5 --- /dev/null +++ b/05- May/18- Minimum Number of Vertices to Reach All Nodes/18- Minimum Number of Vertices to Reach All Nodes (Osama Ayman).java @@ -0,0 +1,20 @@ +// Author: Osama Ayman +// Time: O(N + E) +// Space: O(N) +class Solution { + public List findSmallestSetOfVertices(int n, List> edges) { + boolean[] incomingEdge = new boolean[n]; + for(List e: edges){ + incomingEdge[e.get(1)] = true; + } + List res = new ArrayList<>(); + // Any node that has no incoming edge can not be visited untill we start from it + for(int i=0; i colour; + + // Function to check if a graph is bipartite + bool is_Bipartite(int u, vector < vector < int > >& adj) { + // Iterate over the adjacent vertices of u + for (auto v : adj[u]) { + // If v has the same color as u, the graph is not bipartite + if (colour[v] == colour[u]) + return false; + // If v is uncolored, assign a different color to it + else if (colour[v] == 0) { + colour[v] = -colour[u]; + // Recursively check if the subgraph starting from v is bipartite + if (!is_Bipartite(v, adj)) + return false; + } + } + // All adjacent vertices have been processed and no conflict was found + return true; + } + + bool isBipartite(vector < vector < int > >& graph) { + int n = graph.size(); + colour = vector < int > (n); + + bool isBip = true; + // Process each vertex in the graph + for (int u = 0; u < n; u++) { + // If the vertex is uncolored, assign color 1 to it + if (!colour[u]) { + colour[u] = 1; + // Check if the subgraph starting from u is bipartite + isBip &= is_Bipartite(u, graph); + } + } + + // Return whether the graph is bipartite or not + return isBip; + } + +}; diff --git a/05- May/19- Is Graph Bipartite?/19- Is Graph Bipartite? (Lama Salah).cpp b/05- May/19- Is Graph Bipartite?/19- Is Graph Bipartite? (Lama Salah).cpp new file mode 100644 index 000000000..beb259c0b --- /dev/null +++ b/05- May/19- Is Graph Bipartite?/19- Is Graph Bipartite? (Lama Salah).cpp @@ -0,0 +1,49 @@ +// Author: Lama Salah + +class Solution { +public: + vector> adj; // Adjacency list to represent the graph. + vector vis; // Array to keep track of node colors. + + // Recursive function to check if the graph is not bipartite. + bool isNotBipartite(int node, int color) { + vis[node] = color; // Assign the current node the specified color (0 or 1). + + bool ans = false; // Variable to store the result. + + for (auto& i : adj[node]) { + if (vis[i] == -1) { + // If the neighbor hasn't been visited, recursively call the function with the opposite color. + ans |= isNotBipartite(i, color ^ 1); + } else if ((color ^ 1) != vis[i]) { + // If the neighbor has been visited and has the same color as the current node, the graph is not bipartite. + return true; + } + } + + return ans; + } + + bool isBipartite(vector>& graph) { + adj.assign(graph.size(), vector()); // Initialize the adjacency list. + vis.assign(graph.size(), -1); // Initialize the vis array. + + // Build the adjacency list based on the given graph. + for (int i = 0; i < graph.size(); i++) { + for (auto& j : graph[i]) { + adj[i].push_back(j); + adj[j].push_back(i); + } + } + + // Iterate over each node in the graph. + for (int i = 0; i < graph.size(); i++) { + if (vis[i] == -1 && isNotBipartite(i, 0)) { + // If the node hasn't been visited and the graph is not bipartite, return false. + return false; + } + } + + return true; // The graph is bipartite. + } +}; \ No newline at end of file diff --git a/05- May/19- Is Graph Bipartite?/19- Is Graph Bipartite? (Mahmoud aboelsoud).cpp b/05- May/19- Is Graph Bipartite?/19- Is Graph Bipartite? (Mahmoud aboelsoud).cpp new file mode 100644 index 000000000..02f359ad0 --- /dev/null +++ b/05- May/19- Is Graph Bipartite?/19- Is Graph Bipartite? (Mahmoud aboelsoud).cpp @@ -0,0 +1,58 @@ +// author: Mahmoud Aboelsoud + +class Solution { +public: + // we just need to check if the graph is bipartite or not + // we can do that by coloring the nodes with 2 colors and check if there is a node with 2 colors + // if there is a node with 2 colors then the graph is not bipartite + // else the graph is bipartite + + + // graph: the adjacency list of the graph + vector> graph; + // cols: the color of each node + vector cols; + // n: the number of nodes in the graph + int n; + + // a dfs function to color the nodes + bool dfs(int node, int col){ + // color the node with col + cols[node] = col; + + // iterate over the neighbours of the node + for(auto&i: graph[node]){ + // if the neighbour is not colored then color it with the opposite color of the node + if(cols[i] == -1){ + // if the coloring failed after coloring the neighbour then the graph is not bipartite + if(!dfs(i, !col)) return false; + // if the neighbour is colored then check if it has the same color of the node + }else{ + // if the neighbour has the same color of the node then the graph is not bipartite + if(cols[i] == col) return false; + } + } + // if we reached here then the graph is bipartite + return true; + } + + + bool isBipartite(vector>& graph) { + // initialize the graph and the cols array and the number of nodes + this -> graph = graph; + n = graph.size(); + cols.assign(n, -1); + + // the graph may not be connected so we need to check each component + for(int i = 0; i < n; i++){ + // if the node is not colored then color it with 0 + if(cols[i] == -1){ + // if the coloring failed then the graph is not bipartite + if(!dfs(i, 0)) return false; + } + } + + // if we reached here then the graph is bipartite + return true; + } +}; diff --git a/05- May/19- Is Graph Bipartite?/19- Is Graph Bipartite? (Omar Sanad).cpp b/05- May/19- Is Graph Bipartite?/19- Is Graph Bipartite? (Omar Sanad).cpp new file mode 100644 index 000000000..0cc762bca --- /dev/null +++ b/05- May/19- Is Graph Bipartite?/19- Is Graph Bipartite? (Omar Sanad).cpp @@ -0,0 +1,49 @@ +// author : Omar Sanad + +class Solution { +public: + // declare an array to store the color of each node + int color[101]; + + // an adjacency list, where each node points to its neighbours + vector> adj; + + // a dfs function to check whether a graph is Bipartite or not... + // it keeps track of the current node, and the color of the parent node + bool isBi(int node, int prevColor) { + + // if this node already has a color + if (color[node]) + // then if the color is the same as its parent (its neighbour), the graph is not Bipartite + // else if the color of this node is different from its parent (its neighbour), till now graph not Bipartite + return color[node] != prevColor; + + // declare a variable that checks whether all the neighbours colors can be different from the current node + bool ok = true; + + // assign a color for the current node, give it a color that's different from the previous color + color[node] = 3 - prevColor; + + // iterate over all neighbours of the current node, and check if we can assign them a color different from the current node. + for (auto &child : adj[node]) + ok &= isBi(child, color[node]); + + // return the status till now (is it Bipartite or not)? + return ok; + } + + bool isBipartite(vector>& graph) { + this->adj = graph; + + // declare a variable that checks for each component if it is Bipartite or not + bool ok = true; + + // iterate over each non-visited node (in other words, each connected component), and check if the component is Bipartite or not + for (int i = 0; i < graph.size(); i++) + if (not color[i]) + ok &= isBi(i, 1); + + // return the answer to the problem + return ok; + } +}; diff --git a/05- May/README.md b/05- May/README.md index f7d3b3f40..3396cbb4e 100644 --- a/05- May/README.md +++ b/05- May/README.md @@ -38,6 +38,8 @@ 1. **[Swapping Nodes in a Linked List](#15--swapping-nodes-in-a-linked-list)** 1. **[Swap Nodes in Pairs](#16--swap-nodes-in-pairs)** 1. **[Maximum Twin Sum of a Linked List](#17--maximum-twin-sum-of-a-linked-list)** +1. **[Minimum Number of Vertices to Reach All Nodes](#18--minimum-number-of-vertices-to-reach-all-nodes)** +1. **[Is Graph Bipartite?](#19--is-graph-bipartite)**


@@ -927,4 +929,113 @@ public: }; ``` + +
+

+ +## 18) [Minimum Number of Vertices to Reach All Nodes](https://leetcode.com/problems/minimum-number-of-vertices-to-reach-all-nodes/) + +### Difficulty + +![](https://img.shields.io/badge/Medium-orange?style=for-the-badge) + +### Related Topic + +`Graph` + +### Code + + +```cpp +class Solution { +public: + vector findSmallestSetOfVertices(int n, vector>& edges) { + // Create two arrays to store the count of outgoing and incoming edges for each vertex + vector from(n), to(n); + + // Count the number of outgoing and incoming edges for each vertex + for (auto& vec : edges) { + from[vec[0]]++; // Increment the outgoing edge count for the source vertex + to[vec[1]]++; // Increment the incoming edge count for the destination vertex + } + + // Create a vector to store the result + vector < int > res; + + // Iterate over all vertices + for (int i = 0; i < n; i++) { + // Check if the vertex has outgoing edges but no incoming edges + if (from[i] && !to[i]) + res.push_back(i); // Add the vertex to the result + } + + // Return the result vector + return res; + } + +}; +``` + +
+

+ +## 19) [Is Graph Bipartite?](https://leetcode.com/problems/is-graph-bipartite/) + +### Difficulty + +![](https://img.shields.io/badge/Medium-orange?style=for-the-badge) + +### Related Topic + +`Depth-First Search` `Breadth-First Search` `Union Find` `Graph` + +### Code + + +```cpp +class Solution { +public: + + vector < int > colour; + + // Function to check if a graph is bipartite + bool is_Bipartite(int u, vector < vector < int > >& adj) { + // Iterate over the adjacent vertices of u + for (auto v : adj[u]) { + // If v has the same color as u, the graph is not bipartite + if (colour[v] == colour[u]) + return false; + // If v is uncolored, assign a different color to it + else if (colour[v] == 0) { + colour[v] = -colour[u]; + // Recursively check if the subgraph starting from v is bipartite + if (!is_Bipartite(v, adj)) + return false; + } + } + // All adjacent vertices have been processed and no conflict was found + return true; + } + + bool isBipartite(vector < vector < int > >& graph) { + int n = graph.size(); + colour = vector < int > (n); + + bool isBip = true; + // Process each vertex in the graph + for (int u = 0; u < n; u++) { + // If the vertex is uncolored, assign color 1 to it + if (!colour[u]) { + colour[u] = 1; + // Check if the subgraph starting from u is bipartite + isBip &= is_Bipartite(u, graph); + } + } + + // Return whether the graph is bipartite or not + return isBip; + } + +}; +``` \ No newline at end of file