Largest Color Value in a Directed Graph

hard graph topo sort dp

Problem

Given a directed graph with a color per node, return the max count of any single color along any path, or −1 if there is a cycle.

Inputcolors = "abaca", edges = [[0,1],[0,2],[2,3],[3,4]]
Output3
Path 0→2→3→4 has 'a' counts 3.

from collections import deque
def largest_path_value(colors, edges):
    return _impl(colors, edges)
def _impl(colors, edges):
    n = len(colors)
    adj = [[] for _ in range(n)]
    indeg = [0] * n
    for u, v in edges:
        adj[u].append(v); indeg[v] += 1
    dp = [[0] * 26 for _ in range(n)]
    q = deque()
    for i in range(n):
        if indeg[i] == 0: q.append(i)
    visited = 0
    best = 0
    while q:
        u = q.popleft(); visited += 1
        dp[u][ord(colors[u]) - 97] += 1
        best = max(best, dp[u][ord(colors[u]) - 97])
        for v in adj[u]:
            for c in range(26):
                if dp[u][c] > dp[v][c]: dp[v][c] = dp[u][c]
            indeg[v] -= 1
            if indeg[v] == 0: q.append(v)
    return -1 if visited < n else best
function largestPathValue(colors, edges) {
  const n = colors.length;
  const adj = Array.from({length: n}, () => []);
  const ind = new Array(n).fill(0);
  for (const [u, v] of edges) { adj[u].push(v); ind[v]++; }
  const dp = Array.from({length: n}, () => new Array(26).fill(0));
  const q = [];
  for (let i = 0; i < n; i++) if (ind[i] === 0) q.push(i);
  let head = 0, visited = 0, best = 0;
  while (head < q.length) {
    const u = q[head++]; visited++;
    dp[u][colors.charCodeAt(u) - 97]++;
    best = Math.max(best, dp[u][colors.charCodeAt(u) - 97]);
    for (const v of adj[u]) {
      for (let c = 0; c < 26; c++) if (dp[u][c] > dp[v][c]) dp[v][c] = dp[u][c];
      if (--ind[v] === 0) q.push(v);
    }
  }
  return visited < n ? -1 : best;
}
class Solution {
    public int largestPathValue(String colors, int[][] edges) {
        return solve(colors, edges); }
    int solve(String colors, int[][] edges) {
        int n = colors.length();
        List<List<Integer>> adj = new ArrayList<>(); for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
        int[] ind = new int[n];
        for (int[] e : edges) { adj.get(e[0]).add(e[1]); ind[e[1]]++; }
        int[][] dp = new int[n][26];
        Deque<Integer> q = new ArrayDeque<>();
        for (int i = 0; i < n; i++) if (ind[i] == 0) q.add(i);
        int visited = 0, best = 0;
        while (!q.isEmpty()) {
            int u = q.poll(); visited++;
            int ci = colors.charAt(u) - 'a';
            dp[u][ci]++; best = Math.max(best, dp[u][ci]);
            for (int v : adj.get(u)) {
                for (int c = 0; c < 26; c++) if (dp[u][c] > dp[v][c]) dp[v][c] = dp[u][c];
                if (--ind[v] == 0) q.add(v);
            }
        }
        return visited < n ? -1 : best;
    }
}
int largestPathValue(string colors, vector<vector<int>>& edges) { return solve(colors, edges); }
int solve(string colors, vector<vector<int>>& edges) {
    int n = colors.size();
    vector<vector<int>> adj(n);
    vector<int> ind(n, 0);
    for (auto& e : edges) { adj[e[0]].push_back(e[1]); ind[e[1]]++; }
    vector<vector<int>> dp(n, vector<int>(26, 0));
    queue<int> q;
    for (int i = 0; i < n; i++) if (ind[i] == 0) q.push(i);
    int visited = 0, best = 0;
    while (!q.empty()) {
        int u = q.front(); q.pop(); visited++;
        int ci = colors[u] - 'a';
        dp[u][ci]++; best = max(best, dp[u][ci]);
        for (int v : adj[u]) {
            for (int c = 0; c < 26; c++) if (dp[u][c] > dp[v][c]) dp[v][c] = dp[u][c];
            if (--ind[v] == 0) q.push(v);
        }
    }
    return visited < n ? -1 : best;
}
Time: O((n+m)·26) Space: O(n·26)