Cod sursa(job #2844084)

Utilizator Vlad_AnicaAnica-Popa Vlad-Ioan Vlad_Anica Data 3 februarie 2022 18:39:42
Problema A+B Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.44 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include<cerrno>
#define ll long long
//#define cond if (start == 4)


using namespace std;

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

const long long NMAX = 600, KMAX = 20, IMIC = 1e8;
const ll INF = (long long)IMIC * IMIC;

struct pack {
    long long nd;
    ll cst;
};

struct cmp {
    public: bool operator()(const pack& a, const pack& b) { // returnez 1 daca a are priritatea strict mai mare decat b
        return a.cst > b.cst;
    }
};

bool isk[NMAX];
ll ham[(1 << KMAX)][KMAX + 1];
long long cntham[(1 << KMAX)][KMAX + 1];
long long n;
long long ind[NMAX];
long long kp[KMAX];
ll minDist[NMAX];
ll dk[KMAX][KMAX], dfin[KMAX];
vector<pack> g[NMAX];
priority_queue<pack, vector<pack>, cmp> heap;

void dij(long long start);

int main()
{
    long long m, k, i, j, p, nd1, nd2, nd;
    ll w;
    fin >> n >> m;
    fin >> k;

    isk[0] = 1;
    kp[0] = 0;
    ind[0] = 0;
    dfin[0] = -INF;
    for (i = 1; i <= k; i++) {
        fin >> nd;
        isk[nd] = 1;
        ind[nd] = i;
        dfin[i] = -INF;
        kp[i] = nd;
    }
    for (i = 0; i < m; i++) {
        fin >> nd1 >> nd2 >> w;

        g[nd1].push_back({nd2, w});
        g[nd2].push_back({nd1, w});
    }
    for (i = 0; i <= k; i++)
        for (j = 0; j <= k; j++)
            dk[i][j] = -INF;

    for (i = 0; i <= k; i++)
        dij(kp[i]);




    long long lst = (1 << (k + 1)) - 1, nxst;

    for (i = 0; i <= lst; i++)
        for (j = 0; j <= k; j++) {
            cntham[i][j] = 0;
            ham[i][j] = -INF;
        }

    ham[1][0] = 0;
    for (i = 3; i <= lst; i += 2) {
        for (j = 0; j <= k; j++) {
            if (((i >> j) & 1) == 0)
                continue;

            cntham[i][j] = 0;
            for (p = 0; p <= k; p++)
                if ((i >> p) & 1)
                    cntham[i][j]++;

            for (p = 0; p <= k; p++) {
                if ((p == j) || ((i >> p) & 1) == 0)
                    continue;

                nxst = i ^ (1 << j);
                ham[i][j] = max(ham[i][j], ham[nxst][p] + dk[p][j] * ((cntham[i][j] + 1) & 1));
               // cout << i << " " << j << " " << p << ",  nxst: " << nxst << " "  << ham[nxst][p] << "  -> " << ham[i][j] << endl;
            }
        }
    }

    ll maxx = -INF;
    for (long long i = 1; i <= k; i++)
        maxx = max(maxx, ham[lst][i] + dfin[i]);

    if (k == 0)
        maxx = dfin[0];

    fout << maxx;


    return 0;
}

void dij(long long start) {
    for (long long i = 0; i < n; i++)
        minDist[i] = INF;

    heap = priority_queue<pack, vector<pack>, cmp>();
    minDist[start] = 0;
    heap.push({start, 0});

    while (!heap.empty()) {
        pack curr = heap.top();
        heap.pop();

        if (curr.cst == minDist[curr.nd]) {
            if (isk[curr.nd])
                dk[ind[start]][ind[curr.nd]] = curr.cst;
            if (curr.nd == n - 1) {
                dfin[ind[start]] = curr.cst;
            }

            long long len = g[curr.nd].size();
            for (long long i = 0; i < len; i++) {
                pack nxt = g[curr.nd][i];
                if (minDist[nxt.nd] > curr.cst + nxt.cst) {
                    minDist[nxt.nd] = curr.cst + nxt.cst;
                    heap.push({nxt.nd, minDist[nxt.nd]});
                }
            }
        }

    }
}