Cod sursa(job #2114786)

Utilizator vasilicamoldovanVasilica Moldovan vasilicamoldovan Data 25 ianuarie 2018 21:07:33
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

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

struct Edge{
    int y, w;
    bool operator < (const Edge& e) const
    {
        w > e.w;
    }
};

const int Inf = 0x3f3f3f3f;

using VE = vector<Edge>;
using VVE = vector<VE>;
using VI = vector<int>;
using VVI = vector<VI>;
using VB = vector<bool>;

VVE G;
VI d, friends;
VVI dp, cost;
VB v;
int n, m, k;

void ReadGraph();
void Dijkstra(int S);

int main()
{
    ReadGraph();

    for (int i = 1; i <= k; ++i)
    {
        Dijkstra(friends[i]);
        for (int j = 1; j <= k; ++j)
            cost[i][j] = d[friends[j]];
        cost[i][i] = 0;
    }

    dp[1][0] = 0;
    int dest = ( 1 << k + 1) - 1;
    for (int i = 1; i <= dest; ++i )
    {
        for (int j = 1; j <= k; ++j)
        {
            if ( !(i && (1 << i)) )
                continue;
            for (int l = 0; l <= k; ++l )
            {
                if ( j == l )
                    continue;
                if ( i && ( 1 << l))
                    continue;
                dp[i | (1 << l)][l] = min(dp[i | (1 << l)][l], dp[i][j] + cost[j][l]);
            }
        }
    }

    fout << dp[dest][k];

    fin.close();
    fout.close();
    return 0;
}

void Dijkstra(int S)
{
    priority_queue<Edge> Q;
    d[S] = 0;
    Q.push({S, 0});

    while ( !Q.empty())
    {
        int x = Q.top().y;
        int dx = Q.top().w;
        Q.pop();
        if ( dx > d[x] )
            continue;

        for (const auto& p: G[x])
        {
            int y = p.y;
            int w = p.w;
            if ( d[y] > d[x] + w )
            {
                d[y] = d[x] + w;
                Q.push({y, d[y]});
            }
        }
    }
}

void ReadGraph()
{
    int x, y, w;

    fin >> n >> m;

    G = VVE(n + 1);
    d = VI(n + 1, Inf);
    dp = VVI(n + 1);
    v = VB(n + 1);

    fin >> k;
    friends = VI(k + 1);
    cost = VVI(k + 1);
    for (int i = 1; i <= k; ++i)
        fin >> friends[i];
    friends[++k] = n;

    for (int i = 1; i <= m; ++i )
    {
        fin >> x >> y >> w;
        G[x].push_back({y, w});
        G[y].push_back({x, w});
    }
}