Cod sursa(job #2925323)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 14 octombrie 2022 11:33:29
Problema Gather Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.97 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <bitset>

using namespace std;

ifstream fin("gather.in");
ofstream fout("gather.out");

const int maxN = 755, maxK = 17, inf = 0x3f3f3f3f;
int n, k, m, v[maxK], dist[maxK][maxK][maxN], dp[maxK][(1 << maxK)];
bool used[maxN];
struct mucie {
    int nod, c, cap;
};
vector <mucie> G[maxN];
priority_queue <pair<int, int>> heap;

void dijkstra(int start, int nrp)
{
    for(int i = 1; i <= n; i++)
        dist[start][nrp][i] = inf, used[i] = 0;
    heap.push({0, v[start]});
    dist[start][nrp][v[start]] = 0;
    while(!heap.empty())
    {
        auto curr = heap.top();
        int nod = curr.second, cost = -curr.first;
        heap.pop();
        if(used[curr.second])
            continue;
        used[curr.second] = 1;
        for(auto nxt : G[curr.second])
        {
            if(nxt.cap < nrp)
                continue;
            if(cost + nxt.c < dist[start][nrp][nxt.nod])
            {
                dist[start][nrp][nxt.nod] = cost + nxt.c;
                heap.push({-dist[start][nrp][nxt.nod], nxt.nod});
            }
        }
    }
}

int main()
{
    fin >> k >> n >> m;
    for(int i = 1; i <= k; i++)
        fin >> v[i];
    sort(v + 1, v + k + 1);
    for(int i = 1; i <= m; i++)
    {
        int x, y, c, cc;
        fin >> x >> y >> c >> cc;
        G[x].push_back({y, c, cc});
        G[y].push_back({x, c, cc});
    }
    for(int i = 1; i <= k; i++)
        for(int j = 1; j <= k; j++)
            dijkstra(i, j);
//    for(int i = 1; i <= k; i++)
//    {
//        for(int j = 1; j <= k; j++)
//        {
//            fout << "Nodul de start este " << i << " si numarul de prizonieri e " << j << '\n';
//            for(int ii = 1; ii <= n; ii++)
//                fout << dist[i][j][ii] << ' ';
//            fout << '\n';
//        }
//    }
    for(int i = 0; i < k; i++)
        for(int c = 0; c < (1 << k); c++)
            dp[i][c] = inf;
    for(int i = 0; i < k; i++)
        dp[i][(1 << i)] = dist[i + 1][1][1];
    for(int c = 0; c < (1 << k); c++)
    {
        for(int nod = 0; nod < k; nod++)
        {
            if((c & (1 << nod)) == 0)
                continue;
            for(int vecin = 0; vecin < k; vecin++)
            {
                if(vecin == nod || (c & (1 << vecin)))
                    continue;
                int nrp = __builtin_popcount(c);
                dp[vecin][c ^ (1 << vecin)] = min(dp[vecin][c ^ (1 << vecin)], dp[nod][c] + (nrp + 1) * dist[nod + 1][nrp][v[vecin + 1]]);
            }
        }
    }
    int ans = inf;
//    for(int i = 0; i < k; i++)
//    {
//        for(int c = 0; c < (1 << k); c++)
//        {
//            bitset <2> x(c);
//            fout << i + 1 << ' ' << x << "   " << dp[i][c] << '\n';
//        }
//    }
    for(int i = 0; i < k; i++)
        ans = min(ans, dp[i][(1 << k) - 1]);
    fout << ans;
    return 0;
}