Cod sursa(job #1596283)

Utilizator ZenusTudor Costin Razvan Zenus Data 10 februarie 2016 21:32:24
Problema Ubuntzei Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.23 kb
#include <bits/stdc++.h>

using namespace std;

const int INF = 1000000000;

int a[19] , d[19][19] , len[2009] , mark[2009] , p[19];
vector < pair < int , int > > g[2009];
int n , m , k , result;
priority_queue < pair < int , int > , vector < pair < int , int > > , greater < pair < int , int > > > ip;

void read()
{
    int i , x , y , z;

    scanf("%d" , &n);
    scanf("%d" , &m);

    scanf("%d" , &k);

    a[0] = 1 , a[k + 1] = n;
    for (i = 1 ; i <= k ; ++i)
    scanf("%d" , &a[i]);

    for (i = 1 ; i <= m ; ++i)
    {
        scanf("%d" , &x);
        scanf("%d" , &y);
        scanf("%d" , &z);
        g[x].push_back(make_pair(y , z));
        g[y].push_back(make_pair(x , z));
    }
}

void runDijkstra(int S)
{
    int i , j , x , z;

    for (i = 1 ; i <= n ; ++i)
    {
        len[i] = INF;
        mark[i] = 0;
    }

    ip.push(make_pair(0 , S));
    len[S] = 0;

    while (ip.size())
    {
        i = ip.top().second;
        ip.pop();

        if (mark[i]) continue;
        mark[i] = true;

        for (j = 0 ; j < g[i].size() ; ++j)
        {
            x = g[i][j].first;
            z = g[i][j].second;

            if (len[x] <= len[i] + z) continue;
            len[x] = len[i] + z;
            ip.push(make_pair(len[x] , x));
        }
    }
}

void runD()
{
    int i , j , ai , aj;

    for (i = 0 ; i <= k + 1 ; ++i)
    {
        ai = a[i];
        runDijkstra(ai);

        for (j = 0 ; j <= k + 1 ; ++j)
        {
            aj = a[j];
            d[i][j] = len[aj];
        }
    }

    //for (i = 0 ; i <= k + 1 ; ++i)
    //for (j = 0 ; j <= k + 1 ; ++j)
    //cerr << a[i] << " " << a[j] << " : " << d[i][j] << '\n';
}

void bkt(int stp , int c)
{
    if (stp == k + 1)
    {
        c += d[p[k]][k + 1];
        result = min(result , c);
        return ;
    }

    for (int i = 1 ; i <= k ; ++i)
    {
        if (mark[i]) continue;
        p[stp] = i; mark[i] = 1;

        if (c + d[i][p[stp - 1]] < result)
        bkt(stp + 1 , c + d[i][p[stp - 1]]);

        mark[i] = 0;
    }
}

void solve()
{
    result = INF;

    memset(mark , 0 , sizeof(mark));
    bkt(1 , 0);
    printf("%d\n" , result);
}

int main()
{
freopen("ubuntzei.in" , "r" , stdin);
freopen("ubuntzei.out" , "w" , stdout);

read();
runD();
solve();

return 0;
}