Number of Unicolored Paths between two nodes
MediumUpdated: Aug 22, 2025
Problem
Given an undirected graph where each edge has a color (edge coloring), and two nodes s and d, count the number of distinct paths from s to d such that all edges in the path have the same color.
Input Format
n: Number of vertices (integer, 0-based indexing)edges: List of edges, where each edge is represented as[u, v, color](0-based)s: Source node (integer)d: Destination node (integer)
Examples
Example 1
graph TD A(1) B(0) 2(2) 3(3) 4(4) B -- "1" --- A B -- "2" --- 2 A -- "3" --- 2 A -- "2" --- 3 A -- "4" --- 4 2 -- "3" --- 4 3 -- "2" --- 4 linkStyle 0 stroke:#d62728,stroke-width:3px; linkStyle 1 stroke:#1f77b4,stroke-width:3px; linkStyle 2 stroke:#2ca02c,stroke-width:3px; linkStyle 3 stroke:#1f77b4,stroke-width:3px; linkStyle 4 stroke:#ff7f0e,stroke-width:3px; linkStyle 5 stroke:#2ca02c,stroke-width:3px; linkStyle 6 stroke:#1f77b4,stroke-width:3px;
Input:
n = 6
edges = [
[0, 1, 1],
[0, 2, 2],
[1, 2, 3],
[1, 3, 2],
[1, 4, 4],
[2, 4, 3],
[3, 4, 2]
]
s = 1
d = 4
Output: 3
Explanation: There are three unicolored paths from 1 to 4:
- 1 → 4 (color 4)
- 1 → 2 → 4 (color 3)
- 1 → 3 → 4 (color 2)
Solution
Method 1 – DFS for Each Color
Intuition
For each color, perform a DFS from the source, only traversing edges of that color, and count the number of ways to reach the destination.
Approach
- For each color present in the graph:
- Do a DFS from the source to the destination, only following edges of that color.
- Mark nodes as visited to avoid cycles.
- If the destination is reached, increment the count for that color.
- Sum the counts for all colors.
Code
C++
class Solution {
public:
int countUnicoloredPaths(const std::vector<std::tuple<int,int,int>>& edges, int n, int s, int d) {
std::unordered_map<int, std::vector<std::pair<int,int>>> adj;
std::unordered_set<int> colors;
for (auto& [u, v, c] : edges) {
adj[u].emplace_back(v, c);
adj[v].emplace_back(u, c);
colors.insert(c);
}
int ans = 0;
for (int color : colors) {
std::vector<bool> vis(n+1, false);
ans += dfs(adj, s, d, color, vis);
}
return ans;
}
private:
int dfs(const std::unordered_map<int, std::vector<std::pair<int,int>>>& adj, int u, int d, int color, std::vector<bool>& vis) {
if (u == d) return 1;
vis[u] = true;
int cnt = 0;
for (auto& [v, c] : adj.at(u)) {
if (!vis[v] && c == color) cnt += dfs(adj, v, d, color, vis);
}
vis[u] = false;
return cnt;
}
};
Java
class Solution {
public int countUnicoloredPaths(List<int[]> edges, int n, int s, int d) {
Map<Integer, List<int[]>> adj = new HashMap<>();
Set<Integer> colors = new HashSet<>();
for (int[] e : edges) {
adj.computeIfAbsent(e[0], k -> new ArrayList<>()).add(new int[]{e[1], e[2]});
adj.computeIfAbsent(e[1], k -> new ArrayList<>()).add(new int[]{e[0], e[2]});
colors.add(e[2]);
}
int ans = 0;
for (int color : colors) {
boolean[] vis = new boolean[n+1];
ans += dfs(adj, s, d, color, vis);
}
return ans;
}
private int dfs(Map<Integer, List<int[]>> adj, int u, int d, int color, boolean[] vis) {
if (u == d) return 1;
vis[u] = true;
int cnt = 0;
for (int[] pair : adj.getOrDefault(u, new ArrayList<>())) {
int v = pair[0], c = pair[1];
if (!vis[v] && c == color) cnt += dfs(adj, v, d, color, vis);
}
vis[u] = false;
return cnt;
}
}
Python
class Solution:
def count_unicolored_paths(self, edges: list[tuple[int,int,int]], n: int, s: int, d: int) -> int:
from collections import defaultdict
adj = defaultdict(list)
colors = set()
for u, v, c in edges:
adj[u].append((v, c))
adj[v].append((u, c))
colors.add(c)
def dfs(u, color, vis):
if u == d:
return 1
vis.add(u)
cnt = 0
for v, c in adj[u]:
if v not in vis and c == color:
cnt += dfs(v, color, vis)
vis.remove(u)
return cnt
ans = 0
for color in colors:
ans += dfs(s, color, set())
return ans
Complexity
- ⏰ Time complexity:
O(E * (E + V)), where E is the number of edges and V is the number of vertices. For each color, a DFS is performed. - 🧺 Space complexity:
O(V + E), for adjacency lists and recursion stack.