Cod sursa(job #1614839)

Utilizator andytosaAndrei Tosa andytosa Data 26 februarie 2016 10:39:45
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.96 kb
#include <fstream>
#include <vector>
#include <queue>
#define inf 100000000
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

struct cel{
    int muc, co;
} aux;
struct oras{
    int a, poz;
} orase[20];
queue<int> coada;
vector<cel> ad[2005];
int n, m, x, y, c, cost[20][20], k, val[2010],now,nxt,d[1 << 17][17];

void reset_val(){
    for(int i = 0; i < n; ++i){
        val[i] = inf;
    }
}
int main()
{
    fin >> n >> m >> k;
    orase[0].a = 0;
    orase[0].poz = 0;
    for(int i = 1; i <= k; ++i){
        fin >> orase[i].a;
        orase[i].a--;
        orase[i].poz = i;
    }
    ++k;
    orase[k].a = n - 1;
    orase[k].poz = k;
    for(int i = 1; i <= m; ++i){
        fin >> x >> y >> c;
        x--;
        y--;
        aux.co = c;
        aux.muc = y;
        ad[x].push_back(aux);
        aux.muc = x;
        ad[y].push_back(aux);
    }
    for(int i = 0; i <= k; ++i)
        for(int j = 0; j <= k; ++j)
            cost[i][j] = inf;

    for(int i = 0; i < k; ++i){
        reset_val();
        val[orase[i].a] = 0;
        coada.push(orase[i].a);
        while(!coada.empty()){
            now = coada.front();
            coada.pop();
            int lung = ad[now].size();
            for(int j = 0; j < lung; ++j){
                int nxt = ad[now][j].muc;
                if(val[nxt] > ad[now][j].co + val[now]){
                    val[nxt] = ad[now][j].co + val[now];
                    coada.push(nxt);
                }
            }
        }

        for(int j = 0; j <= k; ++j){
            if(i != j){
                int ok = val[orase[j].a];
                cost[i][j] = cost[j][i] = ok;
            }
        }
    }

    ++k;
    for(int i = 0; i < (1 << k); ++i){
        for(int j = 0; j < k; ++j)
            d[i][j] = inf;
    }
    d[1][0] = 0;
    for(int i = 1; i < (1 << k); ++i){
        for(int j = 0; (1 << j) <= i; ++j){
            if(i & (1 << j)){
                for(int f = 0; (1 << f) <= i; ++f){
                    if(i & (1 << f) && cost[f][j] != inf){
                        d[i][j] = min(d[i][j], d[i ^ (1 << j)][f] + cost[f][j]);
                    }
                }
            }
        }
    }
    fout << d[(1 << k) - 1][k - 1];

    return 0;
}
/*
    TRACTOARE LA REDUCERE :
    for(int i = 0; i < n; ++i){
        fout << i << " : ";
        for(int j = 0; j < ad[i].size(); ++j)
            fout << ad[i][j].muc << ' ';
        fout << '\n';
    }
    for(int j = 0; j < n; ++j)
        if(val[j] != inf)
            fout << val[j] << ' ';
        else
            fout << 0 << ' ';
    fout << '\n';
    fout << k;
    for(int j = 0; j < k; ++j)
        fout << d[(1 << k) - 1][j] << ' ';
    for(int i = 0; i <= k; ++i, fout << '\n')
        for(int j = 0; j <= k; ++j)
            if(cost[i][j] != inf)
                fout << cost[i][j] << ' ';
            else
                fout << 0 << ' ';
*/