Cod sursa(job #2610927)

Utilizator k2e0e0w3qDumitrescu Gheorghe k2e0e0w3q Data 5 mai 2020 21:38:45
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <bits/stdc++.h>
#define K 17
#define N 2000
#define INF 0x3F3F3F3F
using namespace std;

vector <pair <int, int>> G[N+1];
int dist[N+1][N+1], dp[1<<K][K], v[K];

class heap {
public:
    int nod, cost;

    heap(int x, int y) {
        nod=x, cost=y;
    }

    bool operator < (const heap &x) const {
        return this->cost > x.cost;
    }
};

void Dijkstra (int root) {
    dist[root][root]=0;
    priority_queue <heap> PQ;
    PQ.push({root, 0});

    while (!PQ.empty()) {
        auto save=PQ.top();
        PQ.pop();

        if (dist[root][save.nod]==save.cost)
            for (auto it: G[save.nod])
                if (dist[root][it.first] > save.cost + it.second)
                    dist[root][it.first] = save.cost + it.second,
                    dist[it.first][root] = save.cost + it.second,
                    PQ.push({it.first,     save.cost + it.second});
    }
}

int k;
int calc (int mask, int i) {
    if (dp[mask][i]==INF) {
        int i, j;
        for (i=0; i<k; i++)
            if (mask & (1<<i))
                for (j=0; j<k; j++)
                    if (mask & (1<<j) && i!=j)
                        dp[mask][i]=min(dp[mask][i], calc(mask ^ (1<<i), j) + dist[v[j]][v[i]]);
    }
    return dp[mask][i];
}

int main () {
    ifstream fin ("ubuntzei.in");
    ofstream fout ("ubuntzei.out");
    ios::sync_with_stdio(false);

    int n, m;
    fin >> n >> m
        >> k;

    int i, j, c;
    for (i=1; i<=k; i++)
        fin >> v[i];

    v[0]=1;
    v[++k]=n;
    ++k;

    for (; m; m--) {
        fin >> i >> j >> c;
        G[i].push_back(make_pair(j, c));
        G[j].push_back(make_pair(i, c));
    }

    memset(dp, INF, sizeof dp);
    memset(dist, INF, sizeof dist);
    dp[1][0]=0;

    for (i=0; i<k; i++)
        Dijkstra(v[i]);

    int mask;
    for (mask=1; mask<(1<<k); mask++)
        for (i=0; i<k; i++)
            if (mask & (1<<i))
                for (j=0; j<k; j++)
                    if (i!=j && mask & (1<<j))
                        dp[mask][i]=min(dp[mask][i], dp[mask ^ (1<<i)][j] + dist[v[j]][v[i]]);

    fout << dp[(1<<k)-1][k-1];
    return 0;
}