NeoFraMatrix
NeoFraMatrix

Reputation: 13

Kattis problem Dominos, run time error on the final testcase, am i missing something obvious or an edge case?

I have spent a lot of time on the problem Dominos from kattis, see here: https://open.kattis.com/problems/dominos.

I am passing 3 testcases and on the final one I receive a runtime error. I suspect some out of bond errors might occur, but I really can't narrow down to the potential cause of the runtime error. I have pasted my code below and have tried to describe the different steps and the thinking process. I am using Kosaraju's algorithm to identify the strongly connected components, through a DFS followed by a DFS on the reversed edges (Starting from the last node finished from the prior DFS). Afterwards, I condense the graph to now only contain representatives of the SCCs, in order to obtain a directed acyclic graph. From here I count the indegree 0 of the SCC representatives as this will be the amount of bricks necessary to knock over manually by hand. I hope this question is specific enough and some of you might have an idea what could be causing trouble.

from collections import defaultdict

def dfs(brick): # First traversal of graph primarily to generate the DSForder stack for 2nd traversal
    visited.add(brick)
    for neighbour in adj[brick]:
        if neighbour not in visited:
            dfs(neighbour)
    DFSorder.append(brick)

def dfs2(brick):
        visited.add(brick)
        SCCs[SCC_number].append(brick) # Append brick to the Strongly connected component list of bricks
        idx[brick] = SCCs[SCC_number][0] # Set representative as first element in the SCC
        for neighbour in adj_rev[brick]:
            if neighbour not in visited:
                dfs2(neighbour)

t = int(input()) # testcases

for _ in range(t):

    # Long list of needed things
    DFSorder = []
    SCC_number = 0
    SCCs = defaultdict(list)
    IndegreeSCC = defaultdict(int)
    idx=defaultdict(int)
    n,m = list(map(int,input().split()))
    visited = set()
    adj = defaultdict(set)
    adj_rev = defaultdict(set)
    adj_SCC = defaultdict(list)
    
    for _ in range(m):
        brick1,brick2 = list(map(int,input().split()))
        adj[brick1].add(brick2)
        adj_rev[brick2].add(brick1) # Reverse adjacency list for second DFS traversal

    for i in range(1,n+1): # First traversal to generate DFS order
        if i not in visited:
            dfs(i)
    
    visited = set() # Restart visited for 2nd reverse traversal

    for brick in DFSorder[::-1]: # Reverse traversal to determine SCCs
        if brick not in visited:
            dfs2(brick)
            SCC_number += 1
    
    for val in set(idx.values()): # Initially set all indegrees of SCC representatives to 0
        IndegreeSCC[val] = 0

    for key in adj: # Condense graph to SCCs (Only the representatives for each SCC is needed)
        for neighbour in adj[key]:
            if neighbour != idx[key] and idx[key] != idx[neighbour]:
                adj_SCC[idx[key]].append(idx[neighbour])
                IndegreeSCC[idx[neighbour]] += 1
    
    # Bricks that needs to be turned over manually can be found from the indegree 0 Strongly connected components
    print(sum([1 for val in list(IndegreeSCC.values()) if val == 0]))

Upvotes: 1

Views: 947

Answers (0)

Related Questions