Reputation: 13
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