Count unique direct and transitive dependents in a DAG, preserving edge direction, ignoring unknown endpoints, and handling shared descendants without double-counting.
Given named nodes and a dependency DAG, compute how many unique nodes directly or indirectly depend on each node. An edge `[a,b]` means `a` depends on `b`, so `a` contributes to `b`'s count, not the other way around.
Implement `referral_counts(nodes: string[], edges: string[][]) -> int[]`. Return one count per node in the same order as `nodes`; this parallel-array output is a portable representation of the source's name-to-count map.
### Constraints & Assumptions
- Between 0 and 2000 unique nonempty node names and at most 10000 edges. Each edge contains exactly two names.
- Discard an edge if either endpoint is absent from `nodes`. Excluded nodes must not create paths connecting known nodes.
- The remaining graph is a DAG. Duplicate edges may occur and must not multiply reachability counts.
- Count distinct reachable dependents, excluding the node itself. Shared descendants reached by multiple paths count once.
- Isolated nodes have count zero. Names are case-sensitive.
### Example
```text
nodes = ["A","B","C","D","E"]
edges = [["B","A"],["C","A"],["D","B"],["D","C"],
["E","ghost"],["ghost","A"]]
result = [3,1,1,0,0]
```
`D` contributes only once to A. Ignoring the unknown node does not create an E-to-A relationship.
Explain a topological-order approach and why adding child counts is insufficient when dependency paths merge. Compare set or bitset propagation with performing a graph search separately for each node, including time and memory tradeoffs.
```hint Counts alone lose overlap information
When two direct dependents share another dependent, you need enough information to union their reachable nodes without counting that shared node twice.
```
Overview: Count unique direct and transitive dependents in a DAG, preserving edge direction, ignoring unknown endpoints, and handling shared descendants without double-counting.
Given named nodes and a dependency DAG, compute how many unique nodes directly or indirectly depend on each node. An edge [a,b] means a depends on b, so a contributes to b's count, not the other way around.
Implement referral_counts(nodes: string[], edges: string[][]) -> int[]. Return one count per node in the same order as nodes; this parallel-array output is a portable representation of the source's name-to-count map.
Constraints & Assumptions
Between 0 and 2000 unique nonempty node names and at most 10000 edges. Each edge contains exactly two names.
Discard an edge if either endpoint is absent from
nodes
. Excluded nodes must not create paths connecting known nodes.
The remaining graph is a DAG. Duplicate edges may occur and must not multiply reachability counts.
Count distinct reachable dependents, excluding the node itself. Shared descendants reached by multiple paths count once.
Isolated nodes have count zero. Names are case-sensitive.
Example
nodes = ["A","B","C","D","E"]
edges = [["B","A"],["C","A"],["D","B"],["D","C"],
["E","ghost"],["ghost","A"]]
result = [3,1,1,0,0]
D contributes only once to A. Ignoring the unknown node does not create an E-to-A relationship.
Explain a topological-order approach and why adding child counts is insufficient when dependency paths merge. Compare set or bitset propagation with performing a graph search separately for each node, including time and memory tradeoffs.