Cod sursa(job #1895598)

Utilizator hantoniusStan Antoniu hantonius Data 28 februarie 2017 08:01:33
Problema Ubuntzei Scor 45
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <iostream> // sterge
#include <fstream>
#include <algorithm>
#include <vector>
#include <climits>
#define maxn 2002
using namespace std;

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

vector <pair <int, int> > g[maxn];
int n, m, k, viz[maxn], dist[maxn], friends[20], aux, res = INT_MAX, sum, a[20][20];

void read()
{
    int c, x, y;

    fin >> n >> m >> k;
    for (int i = 1; i <= k; i++) {
        fin >> c;
        friends[i] = c;
    }
    for (int i = 1; i <= m; i++) {
        fin >> x >> y >> c;
        g[x].push_back(make_pair(y, c));
        g[y].push_back(make_pair(x, c));
    }
}

void drum(int param)
{
    int vf, ok = 1, poz, minv;
    vector <pair <int, int> >::iterator it;

    vf = friends[param];
    if (k == 0)
        vf = 1;
    for (int i = 1; i <= n; i++)
        viz[i] = 0;
    viz[vf] = 1;
    for (int i = 1; i <= n; i++)
        dist[i] = INT_MAX;
    dist[vf] = 0;
    for (it = g[vf].begin(); it != g[vf].end(); it++)
        dist[it->first] = it->second;
    while (ok == 1) {
        minv = INT_MAX;
        for (int i = 1; i <= n; i++)
            if (viz[i] == 0 && dist[i] < minv) {
                minv = dist[i];
                poz = i;
            }
        if (minv == INT_MAX)
            ok = 0;
        else {
            viz[poz] = 1;
            for (it = g[poz].begin(); it != g[poz].end(); it++)
                if (dist[it->first] > dist[poz] + it->second)
                    dist[it->first] = dist[poz] + it->second;
        }
    }
    if (k == 0) {
        fout << dist[n];
        return ;
    }
    a[0][param] = a[param][0] = dist[1];
    a[k + 1][param] = a[param][k + 1] = dist[n];
    for (int i = 1; i <= k; i++)
        a[param][i] = a[i][param] = dist[friends[i]];
}

void generare(int poz)
{
    if (poz == k + 1) {
        if (sum + a[dist[poz - 1]][k + 1] < res) {
            res = sum + a[dist[poz - 1]][k + 1];
        }
        return ;
    }
    for (int i = 1; i <= k; i++)
        if (viz[i] == 0) {
            dist[poz] = i;
            sum += a[dist[poz - 1]][dist[poz]];
            viz[i] = 1;
            generare(poz + 1);
            viz[i] = 0;
            sum -= a[dist[poz - 1]][dist[poz]];
        }
}

void solve()
{
    for (int i = 1; i <= k; i++)
        drum(i);
    for (int i = 0; i < 20; i++)
        viz[i] = 0;
    dist[0] = 0;
    generare(1);
}

int main()
{
    read();
    if (k != 0) {
        solve();
        fout << res;
    }
    else {
        drum(1);
    }
    return 0;
}