Cod sursa(job #2569699)

Utilizator Anastasia11Susciuc Anastasia Anastasia11 Data 4 martie 2020 13:15:21
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
#define pii pair <int, int>
#define Nmax 2005
#define INF 0x3f3f3f3f

using namespace std;

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

int n, m, k;
int c[Nmax];
vector <pii> v[Nmax];
int dp[(1<<15)+5][17]; // costul minim pentru a ajunge in c[j], trecand prin orasele din starea lui i
int d[Nmax][Nmax];
bool in[Nmax];
struct cmp{
    bool operator()(int a, int b)
    {
        return d[a]>d[b];
    }
};

priority_queue <int, vector <int>, cmp> Q;

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 dist[])
{
    for (int i = 1; i <= n; i++) dist[i]=INF, in[i]=0;
    dist[start]=0;
    Q.push(start);
    in[start]=1;
    while (!Q.empty())
    {
        int x=Q.top();
        in[x]=0;
        Q.pop();
        for (auto i:v[x])
        {
            int y=i.first, c=i.second;
            if (dist[y] > dist[x]+c)
            {
                dist[y]=dist[x]+c;
                if (in[y] == 0)
                {
                    in[y]=1;
                    Q.push(y);
                }
            }
        }
    }
}

int main()
{
    read();
    dijkstra(1, d[1]);
    for (int i = 1; i <= k; i++) dijkstra(c[i], d[c[i]]);
    dijkstra(n, d[n]);
    memset(dp, INF, sizeof(dp));
    if (k == 0)
    {
        g << d[1][n];
        return 0;
    }

    for (int i = 1; i <= k; i++) dp[1<<(i-1)][i]=d[1][c[i]];

    int p=(1<<k);

    for (int i = 1; i < p; 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;

    return 0;
}