Cod sursa(job #2323870)

Utilizator Anastasia11Susciuc Anastasia Anastasia11 Data 19 ianuarie 2019 21:18:43
Problema Ubuntzei Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#define Nmax 2005
#define Kmax 17
#define INF 0x3f3f3f3f

using namespace std;

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

vector <pair <int, int> > v[Nmax];

int n, m, k;
int x, y, c;
int fr[Nmax];
bool vis[Nmax];
int dist[Nmax][Nmax];
int dp[1<<Kmax][Kmax];// distanta minima pentru a ajunge in loc j
                      // cand am trecut prin toate loc din i

struct cmp{
    bool operator()(int x, int y)
    {
        return dist[x]>dist[y];
    }

};

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

void read()
{
    f >> n >> m;
    f >> k;
    for (int i = 1; i <= k; i++)
    {
        f >> fr[i];
    }

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

void print_dist(int d[])
{
    for (int i = 1; i <= n; i++) cout << d[i] << " ";
    cout << '\n';
}

void dijkstra(int st, int d[])
{
    Q.push(st);
    for (int i = 1; i <= n; i++) d[i]=INF;
    d[st]=0;
    vis[st]=1;
    while(!Q.empty())
    {
        int x=Q.top();
        vis[x]=0;
        Q.pop();
        for (int i = 0, l=v[x].size(); i < l; i++)
        {
            int y=v[x][i].first;
            int c=v[x][i].second;
            if(d[x]+c < d[y])
            {
                d[y]=d[x]+c;
                if(vis[y] == 0)
                {
                    vis[y]=1;
                    Q.push(y);
                }
            }
        }
    }
    //print_dist(d);
   // cout << '\n';
}

void print()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
            cout << dist[i][j] << " ";
        cout << '\n';
    }
}

void solve()
{
    for (int i = 1; i <= n; i++)
    {
        memset(vis, 0, sizeof(vis));
        dijkstra(i, dist[i]);
    }

    if(k == 0)
        g << dist[1][n];
    else
    {
         int p=(1<<k);
        memset(dp, INF, sizeof(dp));

        for(int i = 1; i <= k; i++)
            dp[1 << (i - 1)][i] = dist[1][fr[i]];

        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] + dist[fr[l]][fr[j]]);
                    }
                }
            }

        int ans = INF;
        for(int i = 1; i <= k; i++)
            ans = min(ans, dp[p - 1][i] + dist[fr[i]][n]);
        g << ans;
    }
}

int main()
{
    read();
    solve();
    //print_dist();
    return 0;
}