Related Articles

Related Articles

Path with minimum XOR sum of edges in a directed graph
  • Last Updated : 21 Dec, 2020

Given a directed graph with N nodes and E edges, a source S and a destination D nodes. The task is to find the path with the minimum XOR sum of edges from S to D. If there is no path from S to D then print -1.

Examples:  

Input: N = 3, E = 3, Edges = {{{1, 2}, 5}, {{1, 3}, 9}, {{2, 3}, 1}}, S = 1, and D = 3 
Output:
The path with smallest XOR of edges weight will be 1->2->3 
with XOR sum as 5^1 = 4.

Input: N = 3, E = 3, Edges = {{{3, 2}, 5}, {{3, 3}, 9}, {{3, 3}, 1}}, S = 1, and D = 3 
Output: -1 

Approach: The idea is to use Dijkstra’s shortest path algorithm with a slight variation. Below is the step-wise approach for the problem: 



  • Base Case: If the source node is equal to the destination then return 0.
  • Initialise a priority-queue with source node and its weight as 0 and a visited array.
  • While priority queue is not empty: 
    1. Pop the top-most element from priority queue. Let’s call it as current node.
    2. Check if the current node is already visited with the help of the visited array, If yes then continue.
    3. If the current node is the destination node then return the XOR sum distance of the current node from the source node.
    4. Iterate all the nodes adjacent to current node and push into priority queue and their distance as XOR sum with the current distance and edge weight.
  • Otherwise, there is no path from source to destination. Therefore, return -1

Below is the implementation of the above approach: 

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the smallest
// xor sum of edges
double minXorSumOfEdges(
    int s, int d,
    vector<vector<pair<int, int> > > gr)
{
    // If the source is equal
    // to the destination
    if (s == d)
        return 0;
 
    // Initialise the priority queue
    set<pair<int, int> > pq;
    pq.insert({ 0, s });
 
    // Visited array
    bool v[gr.size()] = { 0 };
 
    // While the priority-queue
    // is not empty
    while (pq.size()) {
 
        // Current node
        int curr = pq.begin()->second;
 
        // Current xor sum of distance
        int dist = pq.begin()->first;
 
        // Popping the top-most element
        pq.erase(pq.begin());
 
        // If already visited continue
        if (v[curr])
            continue;
 
        // Marking the node as visited
        v[curr] = 1;
 
        // If it is a destination node
        if (curr == d)
            return dist;
 
        // Traversing the current node
        for (auto it : gr[curr])
            pq.insert({ dist ^ it.second,
                        it.first });
    }
 
    // If no path exists
    return -1;
}
 
// Driver code
int main()
{
    int n = 3;
 
    // Graph as adjacency matrix
    vector<vector<pair<int, int> > >
        gr(n + 1);
 
    // Input edges
    gr[1].push_back({ 3, 9 });
    gr[2].push_back({ 3, 1 });
    gr[1].push_back({ 2, 5 });
 
    // Source and destination
    int s = 1, d = 3;
 
    cout << minXorSumOfEdges(s, d, gr);
 
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.PriorityQueue;
import java.util.ArrayList;
 
class Pair implements Comparable<Pair>
{
    int first, second;
 
    public Pair(int first, int second)
    {
        this.first = first;
        this.second = second;
    }
 
    @Override
    public int compareTo(Pair p)
    {
        if (this.first == p.first)
        {
            return this.second - p.second;
        }
        return this.first - p.first;
    }
}
 
class GFG{
 
// Function to return the smallest
// xor sum of edges
static int minXorSumOfEdges(int s, int d, 
                            ArrayList<ArrayList<Pair>> gr)
{
     
    // If the source is equal
    // to the destination
    if (s == d)
        return 0;
 
    // Initialise the priority queue
    PriorityQueue<Pair> pq = new PriorityQueue<>();
    pq.add(new Pair(0, s));
 
    // Visited array
    boolean[] v = new boolean[gr.size()];
 
    // While the priority-queue
    // is not empty
    while (!pq.isEmpty())
    {
         
        // Iterator<Pair> itr = pq.iterator();
        // Current node
        Pair p = pq.poll();
        int curr = p.second;
 
        // Current xor sum of distance
        int dist = p.first;
 
        // If already visited continue
        if (v[curr])
            continue;
 
        // Marking the node as visited
        v[curr] = true;
 
        // If it is a destination node
        if (curr == d)
            return dist;
 
        // Traversing the current node
        for(Pair it : gr.get(curr))
            pq.add(new Pair(dist ^ it.second, it.first));
    }
 
    // If no path exists
    return -1;
}
 
// Driver code
public static void main(String[] args)
{
    int n = 3;
     
    // Graph as adjacency matrix
    ArrayList<ArrayList<Pair>> gr = new ArrayList<>();
    for(int i = 0; i < n + 1; i++)
    {
        gr.add(new ArrayList<Pair>());
    }
 
    // Input edges
    gr.get(1).add(new Pair(3, 9));
    gr.get(2).add(new Pair(3, 1));
    gr.get(1).add(new Pair(2, 5));
 
    // Source and destination
    int s = 1, d = 3;
    System.out.println(minXorSumOfEdges(s, d, gr));
}
}
 
// This code is contributed by sanjeev2552

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach
from collections import deque
 
# Function to return the smallest
# xor sum of edges
def minXorSumOfEdges(s, d, gr):
     
    # If the source is equal
    # to the destination
    if (s == d):
        return 0
 
    # Initialise the priority queue
    pq = []
    pq.append((0, s))
 
    # Visited array
    v = [0] * len(gr)
 
    # While the priority-queue
    # is not empty
    while (len(pq) > 0):
        pq = sorted(pq)
 
        # Current node
        curr = pq[0][1]
 
        # Current xor sum of distance
        dist = pq[0][0]
 
        # Popping the top-most element
        del pq[0]
 
        # If already visited continue
        if (v[curr]):
            continue
 
        # Marking the node as visited
        v[curr] = 1
 
        # If it is a destination node
        if (curr == d):
            return dist
 
        # Traversing the current node
        for it in gr[curr]:
            pq.append((dist ^ it[1],
                              it[0]))
    # If no path exists
    return -1
 
# Driver code
if __name__ == '__main__':
     
    n = 3
     
    # Graph as adjacency matrix
    gr = [[] for i in range(n + 1)]
 
    # Input edges
    gr[1].append([ 3, 9 ])
    gr[2].append([ 3, 1 ])
    gr[1].append([ 2, 5 ])
 
    # Source and destination
    s = 1
    d = 3
 
    print(minXorSumOfEdges(s, d, gr))
     
# This code is contributed by mohit kumar 29

chevron_right


Output: 

4

 

Time complexity: O((E + V) logV)
 

competitive-programming-img




My Personal Notes arrow_drop_up
Recommended Articles
Page :