Shortest Path in Graph with Weights as either 1 or 2

Last Updated : 13 Jun, 2026

Given a weighted undirected graph with V vertices numbered from 0 to V - 1, represented by an array edges, where edges[i] = [ui, vi, wi] indicates that there is an edge between vertices ui and vi with a weight of wi. (wi can only be 1 or 2), and two vertices src and dest, find the shortest distance from src to dest.

The shortest distance is defined as the minimum total weight required to reach dest starting from src.

Return the shortest distance from src to dest. If dest is not reachable from src, return -1.

Examples:

Input: V = 4, edges[][] = [[0, 1, 1], [0, 2, 2], [2, 3, 1], [1, 2, 1], [1, 3, 2]], src = 0, dest = 3

2056958340

Output: 3
Explanation: One of the shortest paths from vertex 0 to vertex 3 is 0 -> 1 -> 3 with a total weight of 1 + 2 = 3. Another shortest path is 0 -> 2 -> 3 with a total weight of 2 + 1 = 3. Hence, the shortest distance from 0 to 3 is 3.

Input: V = 5, edges[][] = [[0, 1, 1], [0, 2, 2], [1, 2, 1], [3, 4, 2]], src = 1, dest = 3

2056958341

Output: -1
Explanation: There is no path from vertex 1 to vertex 3, so the answer is -1.

Input: V = 5, edges[][] = [[1, 0, 1], [0, 3, 2], [1, 3, 1], [1, 2, 2], [2, 3, 2], [3, 4, 1], [2, 4, 1]], src = 1, dest = 4

2056958339

Output: 2
Explanation: The shortest path from vertex 1 to vertex 4 is 1 -> 3 -> 4 with a total weight of 1 + 1 = 2. Hence, the shortest distance from 1 to 4 is 2.

[Better Approach] - Using Dijkstra algorith - O(E + V log V) and O(V + E) Space

The idea is to use Dijkstra’s shortest path algorithm where we greedily select the node with the minimum current distance, finalize its shortest distance, and use it to relax all adjacent edges. By repeatedly choosing the closest unvisited node, we can find the shortest path from the source to all other nodes in a graph with non-negative edge weights.

[Expected Approach] - Using Edge Splitting Technique + BFS - O(V + E) Time and O(V + E) Space

The idea is to convert the weighted graph into an unweighted graph by splitting every edge with weight 2 into two edges of weight 1 using an intermediate node. After this transformation, the shortest path can be found using simple BFS in O(V + E) time.

C++
#include <iostream>
#include<vector>
#include<queue>
using namespace std;

int shortestPath(int V, int src, int dest, vector<vector<int>> &edges) {

    int extra = V;
    
    // Create adjacency list. Extra nodes
    // are used to split weight 2 edges.
    vector<vector<int>> adj(V + edges.size());

    for (auto &e : edges) {
        int u = e[0];
        int v = e[1];
        int wt = e[2];

        if (wt == 1) {
            
            // Weight 1 edge remains unchanged.
            adj[u].push_back(v);
            adj[v].push_back(u);
        } else {
            
            // Convert weight 2 edge into two weight 1 edges:
            // u -- 1 -- newNode -- 1 -- v
            adj[u].push_back(extra);
            adj[extra].push_back(v);

            adj[v].push_back(extra);
            adj[extra].push_back(u);

            extra++;
        }
    }

    // BFS on the transformed unweighted
    // graph gives shortest distance.
    vector<int> dist(extra, -1);

    queue<int> q;
    q.push(src);
    dist[src] = 0;

    while (!q.empty()) {
        int node = q.front();
        q.pop();

        if (node == dest)
            return dist[node];

        for (int nxt : adj[node]) {
            if (dist[nxt] == -1) {
                dist[nxt] = dist[node] + 1;
                q.push(nxt);
            }
        }
    }

    // Destination is not reachable from source.
    return -1;
}


int main() {
    int V = 4;
    vector<vector<int>> edges = {{0, 1, 1}, {0, 2, 2}, {2, 3, 1}, {1, 2, 1}, {1, 3, 2}};
    int src = 0, dest = 3;
    cout<<shortestPath(V, src, dest, edges)<<endl;
    
    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.Arrays;
import java.util.LinkedList;

public class GFG {
    static int shortestPath(int V, int src, int dest, int[][] edges) {
        int extra = V;
        
        // Create adjacency list. Extra nodes
        // are used to split weight 2 edges.
        List<List<Integer>> adj = new ArrayList<>();
        for (int i = 0; i < V + edges.length; i++)
            adj.add(new ArrayList<>());

        for (int[] e : edges) {
            int u = e[0], v = e[1], wt = e[2];
            if (wt == 1) {
                
                // Weight 1 edge remains unchanged.
                adj.get(u).add(v);
                adj.get(v).add(u);
            } else {
                
                // Convert weight 2 edge into two weight 1 edges:
                // u -- 1 -- newNode -- 1 -- v
                adj.get(u).add(extra);
                adj.get(extra).add(v);
                adj.get(v).add(extra);
                adj.get(extra).add(u);
                extra++;
            }
        }

        // BFS on the transformed unweighted
        // graph gives shortest distance.
        int[] dist = new int[extra];
        Arrays.fill(dist, -1);
        Queue<Integer> q = new LinkedList<>();
        q.add(src);
        dist[src] = 0;

        while (!q.isEmpty()) {
            int node = q.poll();
            if (node == dest) return dist[node];
            for (int nxt : adj.get(node)) {
                if (dist[nxt] == -1) {
                    dist[nxt] = dist[node] + 1;
                    q.add(nxt);
                }
            }
        }
        // Destination is not reachable from source.
        return -1;
    }

    public static void main(String[] args) {
        int V = 4;
        int[][] edges = {{0,1,1},{0,2,2},{2,3,1},{1,2,1},{1,3,2}};
        int src = 0, dest = 3;
        System.out.println(shortestPath(V, src, dest, edges));
    }
}
Python
from collections import deque

def shortestPath(V, src, dest, edges):
    extra = V
    
    # Create adjacency list. Extra nodes
    # are used to split weight 2 edges.
    adj = [[] for _ in range(V + len(edges))]

    for u, v, wt in edges:
        if wt == 1:
            
            # Weight 1 edge remains unchanged.
            adj[u].append(v)
            adj[v].append(u)
        else:
            
            # Convert weight 2 edge into two weight 1 edges:
            # u -- 1 -- newNode -- 1 -- v
            adj[u].append(extra)
            adj[extra].append(v)
            adj[v].append(extra)
            adj[extra].append(u)
            extra += 1

    # BFS on the transformed unweighted
    # graph gives shortest distance.
    dist = [-1] * extra
    dist[src] = 0
    q = deque([src])

    while q:
        node = q.popleft()
        if node == dest:
            return dist[node]
        for nxt in adj[node]:
            if dist[nxt] == -1:
                dist[nxt] = dist[node] + 1
                q.append(nxt)

    # Destination is not reachable from source.
    return -1

if __name__ == "__main__":
    V = 4
    edges = [[0,1,1],[0,2,2],[2,3,1],[1,2,1],[1,3,2]]
    src, dest = 0, 3
    print(shortestPath(V, src, dest, edges))
C#
using System;
using System.Collections.Generic;

class GFG {
    static int ShortestPath(int V, int src, int dest, int[][] edges) {
        int extra = V;
        // Create adjacency list. Extra nodes
        // are used to split weight 2 edges.
        var adj = new List<List<int>>();
        for (int i = 0; i < V + edges.Length; i++)
            adj.Add(new List<int>());

        foreach (var e in edges) {
            int u = e[0], v = e[1], wt = e[2];
            if (wt == 1) {
                
                // Weight 1 edge remains unchanged.
                adj[u].Add(v);
                adj[v].Add(u);
            } else {
                
                // Convert weight 2 edge into two weight 1 edges:
                // u -- 1 -- newNode -- 1 -- v
                adj[u].Add(extra);
                adj[extra].Add(v);
                adj[v].Add(extra);
                adj[extra].Add(u);
                extra++;
            }
        }

        // BFS on the transformed unweighted
        // graph gives shortest distance.
        int[] dist = new int[extra];
        Array.Fill(dist, -1);
        var q = new Queue<int>();
        q.Enqueue(src);
        dist[src] = 0;

        while (q.Count > 0) {
            int node = q.Dequeue();
            if (node == dest) return dist[node];
            foreach (int nxt in adj[node]) {
                if (dist[nxt] == -1) {
                    dist[nxt] = dist[node] + 1;
                    q.Enqueue(nxt);
                }
            }
        }
        
        // Destination is not reachable from source.
        return -1;
    }

    static void Main() {
        int V = 4;
        int[][] edges = { new[]{0,1,1}, new[]{0,2,2}, new[]{2,3,1}, new[]{1,2,1}, new[]{1,3,2} };
        int src = 0, dest = 3;
        Console.WriteLine(ShortestPath(V, src, dest, edges));
    }
}
JavaScript
function shortestPath(V, src, dest, edges) {
    let extra = V;
    // Create adjacency list. Extra nodes
    // are used to split weight 2 edges.
    const adj = Array.from({ length: V + edges.length }, () => []);

    for (const [u, v, wt] of edges) {
        if (wt === 1) {
            
            // Weight 1 edge remains unchanged.
            adj[u].push(v);
            adj[v].push(u);
        } else {
            
            // Convert weight 2 edge into two weight 1 edges:
            // u -- 1 -- newNode -- 1 -- v
            adj[u].push(extra);
            adj[extra].push(v);
            adj[v].push(extra);
            adj[extra].push(u);
            extra++;
        }
    }

    // BFS on the transformed unweighted
    // graph gives shortest distance.
    const dist = new Array(extra).fill(-1);
    const q = [src];
    dist[src] = 0;

    while (q.length > 0) {
        const node = q.shift();
        if (node === dest) return dist[node];
        for (const nxt of adj[node]) {
            if (dist[nxt] === -1) {
                dist[nxt] = dist[node] + 1;
                q.push(nxt);
            }
        }
    }
    
    // Destination is not reachable from source.
    return -1;
}

// Driver code
const V = 4;
const edges = [[0,1,1],[0,2,2],[2,3,1],[1,2,1],[1,3,2]];
const src = 0, dest = 3;
console.log(shortestPath(V, src, dest, edges));

Output
3


Comment