Cod sursa(job #1386547)

Utilizator AdrianaMAdriana Moisil AdrianaM Data 13 martie 2015 02:31:29
Problema Gather Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <set>
#define INF 0x3f3f3f3f
#define pb push_back
#define mp make_pair
using namespace std;

ifstream is("gather.in");
ofstream os("gather.out");

using VB = vector<bool>;
using VI = vector<int>;
using VVI = vector<VI>;

int n, m, k, answ = INF;
VB ok;
VI pr;
VVI g, c, maxp, d;
set<pair<int, pair<int, pair<int, int>>>> s;

void Read();
void Solve();

int main()
{
    Read();
    Solve();
    //os << answ;
    is.close();
    os.close();
    return 0;
}

void Solve()
{
    d = VVI(1 << k, VI(n + 1, INF));
    if ( pr[1] != -1 )
    {
        d[1 << pr[1]][1] = 0;
        s.insert(mp(0, mp(1, mp(1 << pr[1], 1))));
    }
    else
    {
        d[0][1] = 0;
        s.insert(mp(0, mp(1, mp(0, 0))));
    }
    ok = VB(n + 1);
    ok[1] = 1;
    int nod, priz, nrpriz;
    while ( !s.empty() )
    {
        nod = s.begin()->second.first;
        priz = s.begin()->second.second.first;
        nrpriz = s.begin()->second.second.second;
        s.erase(s.begin());
        //cout << nod << " " << d[priz][nod] << "\n";
        //cin.get();
        if ( nrpriz == k )
        {
            os << d[priz][nod] << "\n";
            return;
        }
        for ( const auto& nodv : g[nod] )
            if ( !(priz & ( 1 << pr[nodv] )) )
            if ( pr[nodv] == -1 )
            {
                if ( d[priz][nodv] > d[priz][nod] + ( nrpriz + 1 ) * c[nod][nodv] && nrpriz <= maxp[nod][nodv] )
                {
                    d[priz][nodv] = d[priz][nod] + ( nrpriz + 1 ) * c[nod][nodv];
                    s.insert(mp(d[priz][nodv], mp(nodv, mp(priz, nrpriz))));
                }
            }
            else
                if ( d[priz | (1 << pr[nodv])][nodv] > d[priz][nod] + ( nrpriz + 1 ) * c[nod][nodv] && nrpriz <= maxp[nod][nodv] )
                {
                    d[priz | (1 << pr[nodv])][nodv] = d[priz][nod] + ( nrpriz + 1 ) * c[nod][nodv];
                    s.insert(mp(d[priz | (1 << pr[nodv])][nodv], mp(nodv, mp(priz | (1 << pr[nodv]), nrpriz + 1))));
                }
    }
}

void Read()
{
    is >> k >> n >> m;
    pr = VI(n + 1, -1);
    int n1, n2, cost, nrmax;
    for ( int i = 0; i < k; ++i )
    {
        is >> n1;
        pr[n1] = i;
    }
    g = VVI(n + 1);
    c = VVI(n + 1, VI(n + 1, INF));
    maxp = VVI(n + 1, VI(n + 1));
    for ( int i = 1; i <= n; ++i )
    {
        is >> n1 >> n2 >> cost >> nrmax;
        g[n1].pb(n2);
        g[n2].pb(n1);
        c[n1][n2] = c[n2][n1] = cost;
        maxp[n1][n2] = maxp[n2][n1] = nrmax;
    }
}