Cod sursa(job #2465139)

Utilizator Anastasia11Susciuc Anastasia Anastasia11 Data 29 septembrie 2019 15:03:03
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
#define Nmax 2005
#define Kmax 17
#define INF 0x3f3f3f3f
#define pii pair <int, int>

using namespace std;

ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

int d[Nmax][Nmax]; // distant de la nodul c[i] la j
struct cmp{
    bool operator()(int x, int y)
    {
        return d[x]>d[y];
    }
};

int n, m, k;
int c[Nmax];
bool used[Nmax];
vector <pair <int, int> > v[Nmax];
priority_queue <int, vector <int>, cmp> Q;
int dp[(1<<Kmax)][Nmax]; // dp[i][j]-costul minim pentru a ajunge in orasul j trecand prin orasele
                         // c[x], x - bit de unu din cofiguratia lui i


void read()
{
    f >> n >> m >> k;

    for (int i = 1; i <= k; i++)
        f >> c[i];

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

void dijkstra(int start, int d[])
{
    memset(used, 0, sizeof(used));
    for (int i = 1; i <= n; i++) d[i]=INF;
    // memset(d, INF, sizeof(d));
    used[start]=1;
    d[start]=0;
    Q.push(start);
    while (!Q.empty())
    {
        int x=Q.top();
        Q.pop();
        for (int k = 0; k < v[x].size(); k++)
        {
            int y=v[x][k].first;
            int cost=v[x][k].second;
            if (d[x]+cost < d[y])
            {
                d[y]=d[x]+cost;
                if (!used[y])
                {
                    used[y]=1;
                    Q.push(y);
                }
            }
        }
    }
}

void build_dist()
{

    dijkstra(1, d[1]);
    for (int i = 1; i <= k; i++)
        dijkstra(c[i], d[c[i]]);

    dijkstra(n, d[n]);

    for (int i = 1; i <= n; i++)
        cout << d[1][i] << " ";

    memset(dp, INF, sizeof(dp));

}

void solve()
{
    if (k == 0) g << d[1][n];
    else
    {
        for (int i = 1; i <= k; i++)
            dp[1 << (i - 1)][i] = d[1][c[i]];

        for(int i = 1; i < (1<<k); i++)
            for(int j = 1; j <= k; j++)
            {
                if(i & (1 << (j - 1)))
                {
                    for(int l = 1; l <= k; l++)
                    {
                        if(j == l) continue;
                        if(i & (1 << (l - 1)))
                            dp[i][j] = min(dp[i][j], dp[i ^ (1 << (j - 1))][l] + d[c[l]][c[j]]);
                    }
                }
            }
        int ans = INF;
        for(int i = 1; i <= k; i++)
            ans = min(ans, dp[(1<<k) - 1][i] + d[c[i]][n]);
        g << ans;
    }
}

int main()
{
    read();
    build_dist();
    solve();
    return 0;
}