How many components in a directed graph? - graph

I have the following graph:
The optimal solution is to start dfs from vertex (3) then i will get one component, but when we start the dfs from vertex (1) then (3) i will get two components.
The question is:
I want to know how many components in this graph? or on other way, what is the minimum number of dfs needed to cover all the graph?
what is the needed algorithm for doing this?

You are confusing two definitions.
For undirected graphs there is the notion of connected components, which you find by performing a DFS on the undirected graph.
For directed graphs there is the notion of strongly connected components, for which multiple algorithms are available, all slightly more complicated than a simple DFS.
What you should do depends on which of the two notions you need. Your graph has one connected component when viewed as an undirected graph, and two strongly connected components when viewed as a directed graph.

I know this is an old thread but it would be helpful to add how I solved the problem:
1 - Find the strongly connected components (SCC) inside the graph, and for each SCC, we can replace it with a single node that represents that SCC.
2 - Now, we can know the min number of nodes that we can run DFS from and cover all the other nodes by looking at the degrees of the nodes in the new graph, so we can start DFS from the nodes with zero in degree.

I believe you are trying to find weakly connected components .
Testing whether a directed graph is weakly connected can be done easily in linear time. Simply turn all edges into undirected edges and use the DFS-based connected components algorithm.

To solve this exercise, the idea is to work with an adjacency list of IN-edges.
Take as an example a graph with 3 nodes and 2 edges (0,1) and (0,2), whereas (a,b) indicates that if you switch light a, then light b will also be switched.
OUT-edges adjacency list:
0 -> 1, 2
1 -> _
2 -> _
IN-edges adjacency list:
0 -> _
1 -> 0
2 -> 0
Assuming we don't have cycles, if we follow the IN-edges down until you reach a node which does not have a child, you get what I call an "influencer", that is, you can not switch it with any other node.
Now to take account for cycles I check if any neighbor has or is an influencer. If this is not the case and all neighbors have been visited already, I encounter a cycle and make the current node an influencer.
This is my code (tested with simple examples on my desk):
private int numberOfLights(){
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
List<List<Integer>> inAdjList = new ArrayList<List<Integer>>();
for(int i = 0; i < n; i++){
inAdjList.add(new ArrayList<>());
}
for(int i = 0; i < n; i++){
int from = scanner.nextInt();
int to = scanner.nextInt();
inAdjList.get(to).add(from);
}
int[] visited = new int[n];
int[] isOrHasInfluencer = new int[n];
List<Integer> influencers = new ArrayList<>();
for(int i = 0; i < n; i++){
if(!visited[i]){
DFS(i, visited, isOrHasInfluencer, influencers, inAdjList);
}
}
return influencers.size();
}
private void DFS(Integer cur, int[] visited, int[] isOrHasInfluencer, List<Integer> influencers, List<List<Integer>> inAdjList){
visited[cur] = true;
boolean hasUnvisitedChildren = false;
for(Integer neighbor : inAdjList.get(cur)){
if(!visited[neighbor]){
hasUnvisitedChildren = true;
DFS(neighbor, visited, isOrHasInfluencer, influencers, inAdjList);
}
if(isOrHasInfluencer[neighbor]){
isOrHasInfluencer[cur] = true;
}
}
if(!hasUnvisitedChildren && !isOrHasInfluencer[cur]){
isOrHasInfluencer[cur] = true;
influencers.add(cur);
}
}
Hope that helps! :)

You can run findConnectedComponent algorithm from each of nodes and return the minimum number to solve your specific problem.
I think this solution is not optimal but it works very well with small to medium sized input graph.

Old question, but there is another way.
Convert the directed graph to an undirected one by doing a DFS on all the nodes. O(V+E)
Do what you do for undirected graph. O(V+E)

Related

Recursive Vs iterative Traversal of a BST

If I do recursive traversal of a binary tree of N nodes, it will occupy N spaces in execution stack.
If i use iteration , i will have to use N spaces in an explicit stack.
Question is do we say that recursive traversal is also using O(N) space complexity like iterative one is using?
I am talking in terms of running traversal code on some platform which bounds me by memory limits.
Also i am not talking of directly implementing iteration (in which one can say either of the approaches is fine), I am implementing algorithm for KthSmallestElement() in a BST which uses sort of traversal through the BST.
Should i use iterative approach or recursive approach in terms of space complexity, so that my code doesn't fail in space limits?
Putting it clearly:
Here is what i implemented:
int Solution::kthsmallest(TreeNode* root, int k) {
stack<TreeNode *> S;
while(1)
{
while(root)
{
S.push(root);
root=root->left;
}
root=S.top();
S.pop();
k--;
if(k==0)
return root->val;
root=root->right;
}
}
Here is what my friend implemented:
class Solution {
public:
int find(TreeNode* root, int &k) {
if (!root) return -1;
// We do an inorder traversal here.
int k1 = find(root->left, k);
if (k == 0) return k1; // left subtree has k or more elements.
k--;
if (k == 0) return root->val; // root is the kth element.
return find(root->right, k); // answer lies in the right node.
}
int kthsmallest(TreeNode* root, int k) {
return find(root, k); // Call another function to pass k by reference.
}
};
SO Which of the two is better & how?
If you care about memory use, you should try to ensure that your tree is balanced, i.e. that its depth is smaller than the number of nodes. A perfectly balanced binary tree with N nodes has depth log2N (rounded up).
It is important because the memory needed to visit all nodes in a binary tree is proportional to the depth of the tree, not to the number of nodes as you erroneously think; the recursive or iterative program needs to "remember" the path from the root to the current node, not other previously visited nodes.

Minimum number of jumps required to climb stairs

I recently had an interview with Microsoft for an internship and I was asked this question in the interview.
Its basically like, you have 2 parallel staircases and both the staircases have n steps. You start from the bottom and you may move upwards on either of the staircases. Each step on the staircase has a penalty attached to it.
You can also move across both the staircases with some other penalty.
I had to find the minimum penalty that will be imposed for reaching the top.
I tried writing a recurrence relation but I couldn't write anything because of so many variables.
I recently read about dynamic programming and I think this question is related to that.
With some googling, I found that this question is the same as
https://www.hackerrank.com/contests/frost-byte-final/challenges/stairway
Can you please give a solution or an approach for this problem ?
Create two arrays to keep track of the minimal cost to reach every position. Fill both arrays with huge numbers (e.g. 1000000000) and the start of the arrays with the cost of the first step.
Then iterate over all possible steps, and use an inner loop to iterate over all possible jumps.
foreach step in (0, N) {
// we're now sure we know minimal cost to reach this step
foreach jump in (1,K) {
// updating minimal costs here
}
}
Now every time we reach updating there are 4 possible moves to consider:
from A[step] to A[step+jump]
from A[step] to B[step+jump]
from B[step] to A[step+jump]
from B[step] to B[step+jump]
For each of these moves you need to compute the cost. Because you already know that you have the optimal cost to reach A[step] and B[step] this is easy. It's not guaranteed this new move is an improvement, so only update the target cost in your array if the new cost is lower then the cost already there.
Isn't this just a directed graph search? Any kind of simple pathfinding algorithm could handle this. See
https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
https://en.wikipedia.org/wiki/A*_search_algorithm
Just make sure you enforce the directional of the stairs (up only) and account for penalties (edge weights).
Worked solution
Of course, you could do it with dynamic programming, but I wouldn't be the one to ask for that...
import java.io.;
import java.util.;
public class Main {
public static int csmj(int []a,int src,int[] dp){
if(src>=a.length){
return Integer.MAX_VALUE-1;
}
if(src==a.length-1){
return 0;
}
if(dp[src]!=0){
return dp[src];
}
int count=Integer.MAX_VALUE-1;
for(int i=1;i<=a[src];i++){
count = Math.min( count , csmj(a,src+i,dp)+1 );
}
dp[src] = count;
return count;
}
public static void main(String args[] ) throws Exception {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int a[] = new int[n];
for(int i=0;i<n;i++){
a[i] = s.nextInt();
}
int minJumps = csmj(a,0,new int[n]);
System.out.println(minJumps);
}
}
bro you can have look at that solution my intuition is that

Find the path and max-weigted edge in a Minimax path-finding solution?

I am currently having a programing assignment: given a large weighted unconnected graph (1 < V < 2000,
0 < E < 100 000). Find the maximum-weighted edge along the minimum-weighted path from "source" to point "destination".
What I've got so far is storing the graph in an AdjacencyList (Vector of Vector of IntegerPair where first integer is the neighbor and second is the weight of the edge).
I've also obtained the Minimum Spanning Tree by using Prim's algorithm:
private static void process(int vtx) {
taken.set(vtx, true);
for (int j = 0; j < AdjList.get(vtx).size(); j++) {
IntegerPair v = AdjList.get(vtx).get(j);
if (!taken.get(v.first())) {
pq.offer(new IntegerPair(v.second(), v.first())); //sort by weight then by adjacent vertex
}
}
}
void PreProcess() {
Visited = new Vector<Boolean>();
taken = new Vector<Boolean>();
pq = new PriorityQueue<IntegerPair>();
taken.addAll(Collections.nCopies(V, false));
process(0);
int numTaken = 1;
int mst_cost = 0;
while (!pq.isEmpty() && numTaken != V) { //do this until all V vertices are taken (or E = V - 1 edges are taken)
IntegerPair front = pq.poll();
if (!taken.get(front.second())) { // we have not connected this vertex yet
mst_cost += front.first(); // add the weight of this edge
process(front.second());
numTaken++;
}
}
}
What I am stuck at now is how to find the path from source to destination and return the maxmum weight edge in the below query:
int Query(int source, int destination) {
int ans = 0;
return ans;
}
I was told to use Depth-First Search to traverse the resulting MST but I think the DFS will traverse all vertices that are not on the correct path (am I right?). And how to find the maximum edge?
(This problem is not related to any SSSP algorithm because I haven't been taught Dijstra's, etc.)
One possible way to do this would be to use Kruskal's MST algorithm. It is a greedy algorithm that will start with an empty graph, the repeatedly add the lightest edge that does not produce a cycle. This satisfies the properties of a tree, while assuring the minimum-weighted path.
To find the maximum weighted edge, you can also use the properties of the algorithm. Since you know the that EdgeWeight(n) =< EdgeWeight(n+1), the last edge you add to the graph will be the maximum edge.

How to convert a directed graph to an undirected graph?

How do you convert a directed graph to an undirected graph using an adjacency matrix?
public directedToUndirected(boolean[][] adjMatrix) {
}
Do a boolean OR operation with the original matrix and the transpose of the original.
You could loop through the whole array and flip the indices, assuming you're using 0 and 1's
for (int i=0; i<adjMatrix.length; i++) {
for (int j=0; j<adjMatrix[i].length; j++) {
if (adjMatrix[i][j] == 1) {
adjMatrix[j][i] = 1;
}
}
}
You must find any method that need not to change the information. In all of the above suggested methods edge between node i to j is given to j to i and it is wrong because there is not such edge.
You can change the graph into larger one and make some virtual connections. For example if i has connection to j and j has connection to i you can change i to i' and define new edge between j and i. You also should save this fact that i' is the same as i.

Connectivity of a Graph

int dfs(int graph[MAXNODES][MAXNODES],int visited[],int start) {
int stack[MAXNODES];
int top=-1,i;
visited[start]=1;
stack[++top]=start;
while(top!=-1)
{
start=stack[top];
for(i=0;i<MAXNODES;i++) {
if(graph[start][i]&&visited[i]==0) {
stack[++top]=i;
printf("%d-",i);
visited[i]=1;
break;
}
}
if(i==MAXNODES)
top--;
}
return 0;
}
The above code implements the dfs on a Graph stored as an Adjacency Matrix, I request a suggestion, what change should i be doing to know whether the generated graph is connected or not.
See my answer to an earlier question about strongly connected components.
Your dfs is also very inefficient as written, because you start over scanning at i=0 repeatedly; your stack should remember where you left off and continue from there. Recursion is more natural, but if you have bounded call stack size, then an explicit stack is best (for huge trees only).
Here's a recursive dfs. If you're not interested in storing the dfs tree, you can just store 1 in predecessor[] instead of the node you reached it from):
const unsigned MAXNODES=100;
/* predecessor must be 0-initialized by the caller; nodes graph[n] that are
reached from start will have predecessor[n]=p+1, where graph[pred] is the
predecessor via which n was reached from graph[start].
predecessor[start]=MAXNODES+1 (this is the root of the tree; there is NO
predecessor, but instead of 0, I put a positive value to show that it's
reached).
graph[a][b] is true iff there is a directed arc from a->b
*/
void dfs(bool graph[MAXNODES][MAXNODES],unsigned predecessor[]
,unsigned start,unsigned pred=MAXNODES)
{
if (predecessor[start]) return;
predecessor[start]=pred+1;
for (unsigned i=0;i<MAXNODES;++i)
if (graph[start][i])
dfs(graph,predecessor,i,start);
}
Here's a non-recursive dfs patterned on the above, but using the same stack variable for pred and i (in general you'd have a stack variable for every local variable and parameter that can change in your recursion):
void dfs_iter(bool graph[MAXNODES][MAXNODES],unsigned predecessor[]
,unsigned start)
{
unsigned stack[MAXNODES]; // node indices
unsigned n,pred;
int top=0;
stack[top]=start;
for(;;) {
recurse:
// invariant: stack[top] is the next (maybe reached) node
n=stack[top];
if (!predecessor[n]) { // not started yet
pred=top>0?stack[top-1]:MAXNODES;
//show(n,pred);
predecessor[n]=pred+1;
// the first thing we can reach from n
for (unsigned i=0;i<MAXNODES;++i)
if (graph[n][i] && !predecessor[i]) {
stack[++top]=i; goto recurse; // push
}
}
if (top>0) {
pred=stack[top-1];
// the next thing we can reach from pred after n
for (unsigned i=n+1;i<MAXNODES;++i)
if (graph[pred][i]) {
stack[top]=i; goto recurse; // replace top
}
--top;
} else
return;
}
}
This could be structured without the goto (it's just a named continue to the outmost loop), but without any more real clarity in my opinion.
Anyway, recursive calls are far simpler. There's recursive pseudocode for Tarjan's strongly connected components algorithm you can transcribe fairly directly. If you need help making it non-recursive (explicit stack), ask.
You'd need to store the edges generated by travelling from one node to the next. Then you could verify that all the nodes in the graph are connected by edges.
Run Dijkstra's algorithm. If at the end your queue is empty and some of the vertices aren't colored your graph isn't connected. This is guaranteed linear time, the dfs approach has a worst case analysis of quadratic.

Resources