• + 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);
    }