Sort by

recency

|

102 Discussions

|

  • + 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()
    
  • + 0 comments

    include

    include

    include

    include

    include

    include

    using namespace std;

    const int MAXN = 1005; const int MAXK = 11; const int MAX_MASK = (1 << MAXK);

    int n, m, k; vector> adj[MAXN]; int fish_types[MAXN]; int dist[MAXN][MAX_MASK];

    void dijkstra() { // Priority queue stores {distance, {node, fish_mask}} priority_queue>, vector>>, greater>>> pq;

    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < (1 << k); ++j) {
            dist[i][j] = INT_MAX;
        }
    }
    
    // Start at center 1 with the fish available there.
    dist[1][fish_types[1]] = 0;
    pq.push({0, {1, fish_types[1]}});
    
    while (!pq.empty()) {
        auto [current_dist, state] = pq.top();
        pq.pop();
        int u = state.first;
        int current_mask = state.second;
    
        if (current_dist > dist[u][current_mask]) {
            continue;
        }
    
        // Explore neighbors
        for (auto& edge : adj[u]) {
            int v = edge.first;
            int weight = edge.second;
            int new_mask = current_mask | fish_types[v];
            int new_dist = current_dist + weight;
    
            if (new_dist < dist[v][new_mask]) {
                dist[v][new_mask] = new_dist;
                pq.push({new_dist, {v, new_mask}});
            }
        }
    }
    

    }

    int main() { cin >> n >> m >> k;

    // Read fish types for each center
    for (int i = 1; i <= n; ++i) {
        int t;
        cin >> t;
        int mask = 0;
        for (int j = 0; j < t; ++j) {
            int fish_type;
            cin >> fish_type;
            mask |= (1 << (fish_type - 1));
        }
        fish_types[i] = mask;
    }
    
    // Read roads and build adjacency list
    for (int i = 0; i < m; ++i) {
        int u, v, w;
        cin >> u >> v >> w;
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
    }
    
    dijkstra();
    
    int full_mask = (1 << k) - 1;
    int min_time = INT_MAX;
    
    // Check pairs of paths for the two cats
    for (int mask1 = 0; mask1 < (1 << k); ++mask1) {
        for (int mask2 = 0; mask2 < (1 << k); ++mask2) {
            if ((mask1 | mask2) == full_mask) {
                if (dist[n][mask1] != INT_MAX && dist[n][mask2] != INT_MAX) {
                    min_time = min(min_time, max(dist[n][mask1], dist[n][mask2]));
                }
            }
        }
    }
    
    cout << min_time << endl;
    
    return 0;
    

    }

    
    
  • + 0 comments

    include

    include

    include

    include

    include

    include

    using namespace std;

    const int MAXN = 1005; const int MAXK = 11; const int MAX_MASK = (1 << MAXK);

    int n, m, k; vector> adj[MAXN]; int fish_types[MAXN]; int dist[MAXN][MAX_MASK];

    void dijkstra() { // Priority queue stores {distance, {node, fish_mask}} priority_queue>, vector>>, greater>>> pq;

    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < (1 << k); ++j) {
            dist[i][j] = INT_MAX;
        }
    }
    
    // Start at center 1 with the fish available there.
    dist[1][fish_types[1]] = 0;
    pq.push({0, {1, fish_types[1]}});
    
    while (!pq.empty()) {
        auto [current_dist, state] = pq.top();
        pq.pop();
        int u = state.first;
        int current_mask = state.second;
    
        if (current_dist > dist[u][current_mask]) {
            continue;
        }
    
        // Explore neighbors
        for (auto& edge : adj[u]) {
            int v = edge.first;
            int weight = edge.second;
            int new_mask = current_mask | fish_types[v];
            int new_dist = current_dist + weight;
    
            if (new_dist < dist[v][new_mask]) {
                dist[v][new_mask] = new_dist;
                pq.push({new_dist, {v, new_mask}});
            }
        }
    }
    

    }

    int main() { cin >> n >> m >> k;

    // Read fish types for each center
    for (int i = 1; i <= n; ++i) {
        int t;
        cin >> t;
        int mask = 0;
        for (int j = 0; j < t; ++j) {
            int fish_type;
            cin >> fish_type;
            mask |= (1 << (fish_type - 1));
        }
        fish_types[i] = mask;
    }
    
    // Read roads and build adjacency list
    for (int i = 0; i < m; ++i) {
        int u, v, w;
        cin >> u >> v >> w;
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
    }
    
    dijkstra();
    
    int full_mask = (1 << k) - 1;
    int min_time = INT_MAX;
    
    // Check pairs of paths for the two cats
    for (int mask1 = 0; mask1 < (1 << k); ++mask1) {
        for (int mask2 = 0; mask2 < (1 << k); ++mask2) {
            if ((mask1 | mask2) == full_mask) {
                if (dist[n][mask1] != INT_MAX && dist[n][mask2] != INT_MAX) {
                    min_time = min(min_time, max(dist[n][mask1], dist[n][mask2]));
                }
            }
        }
    }
    
    cout << min_time << endl;
    
    return 0;
    

    }

  • + 0 comments

    Solution in Python

    #!/bin/python3
    
    import math
    import os
    import random
    import re
    import sys
    import heapq as pq
    from collections import defaultdict
    from collections import deque
    
    #
    # 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 getFishset(k, centers, bitset):
        for centerN in range(0, len(centers)):
            centers[centerN] = centers[centerN].rstrip().split()
            limit = int(centers[centerN][0])
            for each_f in range(1, limit + 1):
                bitset[centerN + 1] |= 1 << (int(centers[centerN][each_f]) - 1)
        return bitset
    
    def getPath(n, k, centers, roads, bitset, graph):
        hQ = []
        power2 = 1 << k
        dist = [[999999 for j in range(power2)] for _ in range(n + 1)]
        visited = [[0 for j in range(power2)] for _ in range(n + 1)]
        
        bitset = getFishset(k, centers, bitset)
        pq.heappush(hQ, (0, 1, bitset[1]))
        dist[1][bitset[1]] = 0
    
        while hQ:
            distance, centerN, eachSet = pq.heappop(hQ)
            
            if visited[centerN][eachSet] == 1:
                continue
            visited[centerN][eachSet] = 1
            
            for neighbor in graph[centerN]:
                bitadd = eachSet | bitset[neighbor[0]]
                f_dist = distance + neighbor[1]
                if f_dist < dist[neighbor[0]][bitadd]:
                    dist[neighbor[0]][bitadd] = f_dist
                    pq.heappush(hQ, (f_dist, neighbor[0], bitadd))
        
        totalCost = 999999
        range_l = len(dist[n])
        
        for i in range(range_l - 1, 0, -1):
            if dist[n][i] == 999999:
                continue
            if i == (power2 - 1) and dist[n][i] < totalCost:
                totalCost = dist[n][i]
                continue
            for j in range(1, i):
                if (i | j) == (power2 - 1) and max(dist[n][i], dist[n][j]) < totalCost:
                    totalCost = max(dist[n][i], dist[n][j])
    
        return totalCost
    
    def shop(n, k, centers, roads):
        bitset = [0 for _ in range(n + 1)]
        graph = defaultdict(list)
        
        for each in roads:
            graph[each[0]].append((each[1], each[2]))
            graph[each[1]].append((each[0], each[2]))
    
        totalCost = getPath(n, k, centers, roads, bitset, graph)
        return totalCost
    
    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()
    
  • + 0 comments

    WTF this question is way too hard for a 40 score medium question. had to run dynamic programming on subsets of fishes, with a run of dijkstra at each subset, to get the answer

    O(2^k * (k*V + (V+E)*log(V)))

    void dijkstra(int N, const vector<vector<pair<int, int>>>& edges, vector<vector<long>>& distance, int subset) {
        set<pair<long, int>> S;
        for (int i=1; i <= N; ++i) {
            if (distance[subset][i] != LONG_MAX) S.insert({distance[subset][i], i});
        }
        while (!S.empty()) {
            int shortest = S.begin()->second;
            S.erase(S.begin());
            for (auto e : edges[shortest]) {
                if (distance[subset][e.first] > distance[subset][shortest] + e.second) {
                    S.erase({ distance[subset][e.first], e.first});
                    distance[subset][e.first] = distance[subset][shortest] + e.second;
                    S.insert({ distance[subset][e.first], e.first });
                }
            }
        }
    }
    
    int shop(int N, int k, const vector<vector<int>>& fishes, const vector<vector<pair<int, int>>>& roads) {
        int totalSubsets = pow(2, k);
        vector<vector<long>> distance(totalSubsets, vector<long>(N + 1, LONG_MAX));
        distance[0][1] = 0;
        dijkstra(N, roads, distance, 0);
        for (int subset = 1; subset < totalSubsets; ++subset) {
            for (int fish = 1, bit = 1; fish <= k; ++fish, bit <<= 1) {
                if ((subset & bit) == 0) continue;
                for (int shop : fishes[fish]) distance[subset][shop] = min(distance[subset][shop], distance[subset^bit][shop]);
            }
            dijkstra(N, roads, distance, subset);
        }
        long answer = LONG_MAX;
        for (int subset = 0; subset < totalSubsets; ++subset) {
            answer = min(answer, max(distance[subset][N], distance[subset^(totalSubsets - 1)][N]));
        }
        return answer;
    }
    
    int main()
    {
        int n, m, k, fishTypes, fish, x, y, w;
        cin >> n >> m >> k;
        vector<vector<int>> fishes(k + 1);
        vector<vector<pair<int, int>>> roads(n + 1);
        for (int shop = 1; shop <= n; ++shop) {
            cin >> fishTypes;
            for (int type = 1; type <= fishTypes; ++type) {
                cin >> fish;
                fishes[fish].push_back(shop);
            }
        }
        for (int j=1; j <= m; ++j) {
            cin >> x >> y >> w;
            roads[x].push_back({y, w});
            roads[y].push_back({x, w});
        }
        cout << shop(n, k, fishes, roads);
    }