Skip to content

Latest commit

 

History

History
99 lines (93 loc) · 2.45 KB

topological_sorting.md

File metadata and controls

99 lines (93 loc) · 2.45 KB

Topological sorting

from collections import defaultdict, deque
def largestPathValue(colors, edges):
    """
    :type colors: str
    :type edges: List[List[int]]
    :rtype: int
    """
    """
    Topological sorting:
    Order all nodes of a directed graph so that no node points to a node that precedes it.
    First count the indegree of every node. Remove a node with indegree 0, then decrease the indegree of each node it points to by one.
    Repeat until all nodes have been removed.
    If nodes remain but none has indegree 0, the graph contains a cycle and has no topological ordering, which means there is no solution in many problems.
    """
    n = len(colors)
    # Indegree of each node
    degree = [0] * n
    graph = defaultdict(set)
    for a, b in edges:
        degree[b] += 1
        graph[a].add(b)

    # dp: maximum count of each color on reaching each node
    dp = [[0] * 26 for _ in range(n)]
    # Topological sorting
    q = [i for i in range(n) if not degree[i]]
    count = 0
    while q:
        count += 1
        i = q.pop()
        # On visiting node i, add its color
        dp[i][ord(colors[i]) - ord('a')] += 1
        for j in graph[i]:
            degree[j] -= 1
            # When moving from node i to node j, inherit each color count from i if it exceeds the current value
            for c in range(26):
                dp[j][c] = max(dp[j][c], dp[i][c])
            if degree[j] == 0:
                q.append(j)
    # The topological sort detected a cycle
    if count != n:
        return -1
    return max(max(dp[i]) for i in range(n))
package main

import (
    "container/list"
)

func largestPathValue(colors string, edges [][]int) (ans int) {
	n := len(colors)
	graph := make(map[int][]int)
	indegree := make([]int, n)
	for _, edge := range edges {
		u, v := edge[0], edge[1]
		graph[u] = append(graph[u], v)
		indegree[v]++
	}
	queue := list.New()
	for i, degree := range indegree {
		if degree == 0 {
			queue.PushBack(i)
		}
	}
	dp := make([][]int, n)
	for i := range dp {
		dp[i] = make([]int, 26)
	}
	count := 0
	for queue.Len() > 0 {
		node := queue.Front()
		queue.Remove(node)
		count++
		u := node.Value.(int)
		dp[u][colors[u]-'a']++
		ans = max(ans, dp[u][colors[u]-'a'])
		for _, v := range graph[u] {
			for i := range dp[v] {
				dp[v][i] = max(dp[v][i], dp[u][i])
			}
			indegree[v]--
			if indegree[v] == 0 {
				queue.PushBack(v)
			}
		}
	}
	if count < n {
		return -1 // Cycle detected
	}
	return
}