Submission #990806

# Submission time Handle Problem Language Result Execution time Memory
990806 2024-05-31T12:12:01 Z andrei_iorgulescu Cities (BOI16_cities) C++14
37 / 100
565 ms 38972 KB
#include <bits/stdc++.h>

using namespace std;

#define int long long

int inf = 1e18;

int n,k,m;
vector<int> imp;
vector<pair<int,int>> g[200005];
int dp[100005][16];
vector<int> d[5];

vector<int> dijkstra(int nod0)
{
    vector<int> dist(n + 1);
    for (int i = 1; i <= n; i++)
        dist[i] = inf;
    priority_queue<pair<int,int>> pq;
    pq.push({0,nod0});
    while (!pq.empty())
    {
        int nod = pq.top().second,cost = -pq.top().first;
        pq.pop();
        if (dist[nod] == inf)
        {
            dist[nod] = cost;
            for (auto vecin : g[nod])
            {
                pq.push({-(vecin.second + cost),vecin.first});
            }
        }
    }
    return dist;
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> n >> k >> m;
    for (int i = 1; i <= k; i++)
    {
        int x;
        cin >> x;
        imp.push_back(x);
    }
    for (int i = 1; i <= m; i++)
    {
        int x,y,z;
        cin >> x >> y >> z;
        g[x].push_back({y,z});
        g[y].push_back({x,z});
    }
    k--;
    for (int i = 0; i < k; i++)
        d[i] = dijkstra(imp[i]);
    for (int mask = 1; mask < (1 << k); mask++)
    {
        for (int nod = 1; nod <= n; nod++)
        {
            dp[nod][mask] = inf;
            for (int mask2 = 1; mask2 <= mask; mask2++)
            {
                if ((mask & mask2) != mask2)
                    continue;
                int lft = 0;
                for (int bit = 0; bit < k; bit++)
                {
                    if ((1 << bit) & mask2)
                        lft += d[bit][nod];
                }
                dp[nod][mask] = min(dp[nod][mask],dp[nod][mask - mask2] + lft);
            }
        }
        /*for (int nod = 1; nod <= n; nod++)
        {
            vector<vector<int>> dpp;
            dpp.resize(g[nod].size());
            for (int i = 0; i < g[nod].size(); i++)
                dpp[i].resize((1 << k));
            for (int i = 0; i < g[nod].size(); i++)
            {
                if (i == 0)
                {
                    for (int j = 0; j < (1 << k); j++)
                    {
                        if ((j & mask) != j)
                            continue;
                        if (j != 0)
                            dpp[i][j] = dpp[g[nod][0].first][j] + g[nod][0].second;
                    }
                }
                else
                {
                    for (int j = 0; j < (1 << k); j++)
                    {
                        if ((j & mask) != j)
                            continue;
                        dpp[i][j] = inf;
                        if (j == 0)
                            dpp[i][j] = 0;
                        else
                        {
                            for (int jj = 1; jj < (1 << k); jj++)
                            {
                                if ((j & jj) != jj)
                                    continue;
                                dpp[i][j] = min(dpp[i][j],dpp[i - 1][j - jj] + g[nod][i].second + dp[g[nod][i].first][jj]);
                            }
                        }
                    }
                }
            }
            dp[nod][mask] = min(dp[nod][mask],dpp[g[nod].size() - 1][mask]);
        }*/
        vector<pair<int,int>> ord;
        for (int nod = 1; nod <= n; nod++)
            ord.push_back({dp[nod][mask],nod});
        sort(ord.begin(),ord.end());
        for (auto it : ord)
        {
            for (auto vecin : g[it.second])
            {
                dp[it.second][mask] = min(dp[it.second][mask],vecin.second + dp[vecin.first][mask]);
            }
        }
    }
    cout << dp[imp[k]][(1 << k) - 1];
    return 0;
}

/*
4 2 6
1 3
1 2 4
1 3 9
1 4 6
2 3 2
2 4 5
3 4 8
*/

/**
as vrea sa imi fac un dp[nod][mask] = presupunand ca am plecat din imp[0] si am drum spre nod, cat imi mai ia ca sa ma conectez cu nod de mask
1.dp[nod][mask] ar putea fi dp[nod][mask2], mask2 inclus in mask cu tranzitia dp[nod][mask2] + sum(dist(nd,nod)) cu nd special in mask - mask2
acum sa presupun ca nu leg nodul nod de cnv in mod direct
2.dp[nod][mask] ar putea fi sum(dp[vec][mask_vec] + cost_edge_nod_vec) cu reuniune(mask_vec) = mask, mask_vec disjuncte (caz pe care iau macar 2 vecini)
3.dp[nod][mask] = cost_edge_nod_vec + dp[vec][mask], pe care ordinea in care calculez e gen dupa dp-uri inainte de a lua cazul asta
Complexitate: O(intra in timp)
**/
# Verdict Execution time Memory Grader output
1 Correct 1 ms 4956 KB Output is correct
2 Correct 1 ms 4956 KB Output is correct
3 Correct 1 ms 4956 KB Output is correct
4 Correct 1 ms 4956 KB Output is correct
5 Correct 1 ms 5196 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 239 ms 33172 KB Output is correct
2 Incorrect 223 ms 36532 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 5468 KB Output is correct
2 Correct 3 ms 5464 KB Output is correct
3 Correct 3 ms 5468 KB Output is correct
4 Correct 4 ms 5468 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 351 ms 33976 KB Output is correct
2 Correct 342 ms 37320 KB Output is correct
3 Incorrect 149 ms 30984 KB Output isn't correct
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 565 ms 34612 KB Output is correct
2 Incorrect 539 ms 38972 KB Output isn't correct
3 Halted 0 ms 0 KB -