Cod sursa(job #2349377)

Utilizator rexlcdTenea Mihai rexlcd Data 20 februarie 2019 13:43:51
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <set>

using namespace std;

const int INF = 0x3f3f3f3f;
const int MAXN = 2002, MAXK = 15;

set < pair < int , int > > s;
vector < pair < int , int > > v[MAXN];

int n, m, k;
int C[MAXK];
int path1[MAXN], path[MAXK][MAXN], d[1 << MAXK][MAXK];

void dijkstra(int source, int result[])
{
    for(int i = 1; i <= n; i++)
        result[i] = INF;
    result[source] = 0;
    for(int i = 1; i <= n; i++)
        s.insert({result[i], i});

    while(!s.empty())
    {
        int cost = (*s.begin()).first, x = (*s.begin()).second;
        s.erase({cost, x});

        for(int i = 0; i < v[x].size(); i++)
        {
            int y = v[x][i].first, c = v[x][i].second;
            if(result[x] + c < result[y])
            {
                s.erase({result[y], y});
                result[y] = result[x] + c;
                s.insert({result[y], y});
            }
        }
    }
}

int main()
{
    ifstream f("ubuntzei.in");
    ofstream g("ubuntzei.out");
    f >> n >> m >> k;
    for(int i = 0; i < k; i++)
        f >> C[i];
    for(int i = 1, a, b, c; i <= m; i++)
    {
        f >> a >> b >> c;
        v[a].push_back({b, c});
        v[b].push_back({a, c});
    }

    dijkstra(1, path1);
    if(!k)
    {
        g << path1[n] << '\n';
        return 0;
    }

    memset(d, INF, sizeof(d));
    for(int i = 0; i < k; i++)
        dijkstra(C[i], path[i]);
    for(int conf = 1, bit; conf <= (1 << k) - 1; conf++)
    {
        for(bit = 0; bit < k; bit++)
            if(conf == (1 << bit))
                break;
        if(bit < k && conf == (1 << bit))
        {
            d[conf][bit] = path1[C[bit]];
            continue;
        }

        for(bit = 0; bit < k; bit++)
            if(conf & (1 << bit))
            {
                for(int b = 0; b < k; b++)
                    if(bit != b && (conf & (1 << b)))
                    {
                        d[conf][bit] = min(d[conf][bit], d[conf - (1 << bit)][b] + path[b][C[bit]]);
                    }
            }
    }

    int ans = INF;
    for(int i = 0; i < k; i++)
        ans = min(ans, d[(1 << k) - 1][i] + path[i][n]);
    g << ans << '\n';
    f.close();
    g.close();
    return 0;
}