Cod sursa(job #1621886)

Utilizator radarobertRada Robert Gabriel radarobert Data 29 februarie 2016 22:36:28
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>

using namespace std;

const int INF = 0x3f3f3f3f;

priority_queue< pair<int, int> > pq;
queue<pair <int, int> > q;
vector<int> g[2002];
vector<int> cost[2002];
int d[17][2002];
int friends[20];
int df[20][20];
bool vis[17][2002];
int config1[17][131075];
bool inq1[17][131075];

int main()
{
    ifstream in("ubuntzei.in");
    ofstream out("ubuntzei.out");

    int n, m;
    in >> n >> m;

    int k;
    in >> k;
    friends[0] = 1;
    for (int i = 1; i <= k; i++)
        in >> friends[i];
    friends[k+1] = n;

    for (int i = 1, x, y, c; i <= m; i++)
    {
        in >> x >> y >> c;
        g[x].push_back(y);
        g[y].push_back(x);
        cost[x].push_back(c);
        cost[y].push_back(c);
    }

    for (int start = 0; start <= k+1; start++)
    {
        for (int i = 1; i <= n; i++)
            d[start][i] = INF;
        d[start][friends[start]] = 0;
        pq.push(make_pair(0, friends[start]));

        while (!pq.empty())
        {
            int node = pq.top().second;
            pq.pop();
            if (vis[start][node])
                continue;
            vis[start][node] = true;
            for (int i = 0; i < g[node].size(); i++)
                if (d[start][g[node][i]] > d[start][node] + cost[node][i])
                {
                    d[start][g[node][i]] = d[start][node] + cost[node][i];
                    pq.push(make_pair(-d[start][g[node][i]], g[node][i]));
                }
        }
    }

    for (int i = 0; i <= k+1; i++)
    {
        for (int j = 0; j <= k+1; j++)
        {
            df[i][j] = d[i][friends[j]];
            //out << df[i][j] << ' ';
        }
        //out << '\n';
    }

    if (k == 0)
    {
        out << df[0][1] << '\n';
        return 0;
    }

    k++;

    int sol = INF;

    q.push(make_pair(0, 1));
    config1[0][1] = 0;
    inq1[0][1] = true;
    while (!q.empty())
    {
        int last = q.front().first;
        int config = q.front().second;
        q.pop();

        for (int i = 1; i <= k; i++)
            if (!(config & (1<<i)))
            {
                int nc = config | (1<<i);
                if (config1[i][nc] > config1[last][config] + df[last][i] || config1[i][nc] == 0)
                {
                    config1[i][nc] = config1[last][config] + df[last][i];
                    if (!inq1[i][nc])
                    {
                        q.push(make_pair(i, nc));
                        inq1[i][nc] = true;
                    }
                }
            }
    }

    out << config1[k][(1<<(k+1))-1] << '\n';

    return 0;
}