• + 0 comments
    import math
    import os
    import heapq  # Import heapq for the priority queue
    import re
    import sys
    
    #
    # Complete the 'shop' function below.
    #
    # The function is expected to return an INTEGER.
    # The function accepts following parameters:
    #  1. INTEGER n
    #  2. INTEGER k
    #  3. STRING_ARRAY centers
    #  4. 2D_INTEGER_ARRAY roads
    #
    
    def shop(n, k, centers, roads):
        # Step 1: Pre-process the centers input to store fish masks
        fish_masks = [0] * (n + 1)
        for i, center_fish_str in enumerate(centers):
            # The input is a string of space-separated integers
            center_fish = list(map(int, center_fish_str.split()))
            if not center_fish:
                continue
            # The first integer is the count, the rest are fish types
            num_fish = center_fish[0]
            for j in range(1, num_fish + 1):
                fish_type = center_fish[j]
                fish_masks[i + 1] |= (1 << (fish_type - 1))
        
        # Step 2: Build the adjacency list for the graph
        adj = [[] for _ in range(n + 1)]
        for road in roads:
            u, v, w = road
            adj[u].append((v, w))
            adj[v].append((u, w))
        
        # Step 3: Run Dijkstra's with a state-space (node, fish_mask)
        # distances[node][mask] stores the minimum time to reach 'node' having collected fish in 'mask'
        distances = [[float('inf')] * (1 << k) for _ in range(n + 1)]
        
        # Priority queue: (time, node, fish_mask)
        pq = [(0, 1, fish_masks[1])]
        distances[1][fish_masks[1]] = 0
    
        while pq:
            time, u, mask = heapq.heappop(pq)
    
            if time > distances[u][mask]:
                continue
    
            for v, weight in adj[u]:
                new_mask = mask | fish_masks[v]
                new_time = time + weight
    
                if new_time < distances[v][new_mask]:
                    distances[v][new_mask] = new_time
                    heapq.heappush(pq, (new_time, v, new_mask))
    
        # Step 4: Calculate the minimum time for two cats
        min_total_time = float('inf')
        full_mask = (1 << k) - 1
    
        for mask1 in range(1 << k):
            for mask2 in range(mask1, 1 << k):
                if (mask1 | mask2) == full_mask:
                    # Time is the maximum of the two cats' path times
                    time_cat1 = distances[n][mask1]
                    time_cat2 = distances[n][mask2]
                    
                    # Check for unreachable states
                    if time_cat1 != float('inf') and time_cat2 != float('inf'):
                        min_total_time = min(min_total_time, max(time_cat1, time_cat2))
    
        return min_total_time
    
    
    if __name__ == '__main__':
        fptr = open(os.environ['OUTPUT_PATH'], 'w')
    
        first_multiple_input = input().rstrip().split()
    
        n = int(first_multiple_input[0])
    
        m = int(first_multiple_input[1])
    
        k = int(first_multiple_input[2])
    
        centers = []
    
        for _ in range(n):
            centers_item = input()
            centers.append(centers_item)
    
        roads = []
    
        for _ in range(m):
            roads.append(list(map(int, input().rstrip().split())))
    
        res = shop(n, k, centers, roads)
    
        fptr.write(str(res) + '\n')
    
        fptr.close()