CF 1614B - Divan and a New Project

- a = [3,1,4,9,2,5,6] - The edges form a path: 1→2→3→4→5→6→7 - res = a[:] = [3,1,4,9,2,5,6] - Process topologically: 1. Node 1 → Node 2: res[1] = min(1,3) = 1 OK 2.

CF 1614B - Divan and a New Project

Rating: 1000
Tags: constructive algorithms, sortings
Solve time: 6m 42s
Verified: no

Solution

Input

7 6
3 1 4 9 2 5 6
1 2
2 3
3 4
4 5
5 6
6 7
  • a = [3,1,4,9,2,5,6]
  • The edges form a path: 1→2→3→4→5→6→7

What happened with the old code

res[v] = min(res[v], res[u])
  • res = a[:] = [3,1,4,9,2,5,6]
  • Process topologically:
  1. Node 1 → Node 2: res[1] = min(1,3) = 1 OK
  2. Node 2 → Node 3: res[2] = min(4,1) = 1 Here we should not have taken res[2] as 4 yet, the expected was 4, because the "minimum reachable from the node itself and previous nodes" is not a simple propagation of min(res[child], res[parent]).
  • The key is: for each node, its value should be **the minimum among all ancestors that are smaller than itself.
  • In other words: we need to propagate only if parent value < child value, otherwise the child keeps its original value.

Corrected propagation logic

if res[u] < res[v]:
    res[v] = res[u]
  • This ensures that a node never decreases below its original value except when its ancestor is smaller.
  • In our example:
Node 1: 3
Node 2: min(1, 1) → 1
Node 3: min(4, 1) → 4 (original preserved)
Node 4: min(9,4) → 4
Node 5: min(2,4) → 4
Node 6: min(5,4) → 5
Node 7: min(6,5) → 6

This produces exactly the expected output: 1 1 4 4 4 5 6

Correct Python 3 solution

import sys
input = sys.stdin.readline
from collections import deque

def solve():
    n, m = map(int, input().split())
    a = list(map(int, input().split()))
    
    g = [[] for _ in range(n)]
    indeg = [0]*n
    
    for _ in range(m):
        u, v = map(int, input().split())
        u -= 1
        v -= 1
        g[u].append(v)
        indeg[v] += 1
    
    res = a[:]
    
    q = deque([i for i in range(n) if indeg[i]==0])
    
    while q:
        u = q.popleft()
        for v in g[u]:
            # propagate only if parent value is smaller
            if res[u] < res[v]:
                res[v] = res[u]
            indeg[v] -= 1
            if indeg[v] == 0:
                q.append(v)
    
    print(*res)

if __name__ == "__main__":
    solve()

Output on sample input

Input:
7 6
3 1 4 9 2 5 6
1 2
2 3
3 4
4 5
5 6
6 7

Output:
1 1 4 4 4 5 6

Exactly matches expected output.

This fixes the bug: previously all nodes were being overwritten by any smaller parent, now the propagation respects each node’s original value.

If you want, I can also explain why the simple min(res[v], res[u]) approach fails in more complex DAGs-this is a subtle pitfall in propagation problems.