Cod sursa(job #2142249)

Utilizator SolcanMihaiSolcan Mihai Andrei SolcanMihai Data 24 februarie 2018 21:17:55
Problema Ubuntzei Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.11 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

const int inf = 1000000;

int n, m, k;
int c[2002];
vector<pair<int, int> > vecini[2005];
int distante[20][20];
int viz[2005];
int d[2005];

priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > Q;

void citire(){
    scanf("%d %d", &n, &m);
    scanf("%d", &k);

    c[0] = 0;

    for(int i = 0; i < k; i++){
        scanf("%d", &c[i + 1]);
        c[i + 1]--;
    }

    k++;
    c[k] = n - 1;
    k++;

    int tmp1, tmp2, tmp3;

    for(int i = 0; i < m; i++){
        scanf("%d %d %d", &tmp1, &tmp2, &tmp3);
        tmp1--;
        tmp2--;

        vecini[tmp1].push_back({tmp2, tmp3});
        vecini[tmp2].push_back({tmp1, tmp3});
    }
}

void dijkstra(int s){
    while(!Q.empty()){
        Q.pop();
    }

    for(int i = 0; i <= n; i++){
        viz[i] = 0;
        d[i] = 0;
    }

    Q.push({0, c[s]});

    while(!Q.empty()){
        int x = Q.top().second;
        int y = Q.top().first;
        Q.pop();

        if(viz[x] == true){
            continue;
        }

        d[x] = y;
        viz[x] = true;

        int l = vecini[x].size();

        for(int i = 0; i < l; i++){
            if(viz[vecini[x][i].first] == false){
                Q.push({y + vecini[x][i].second, vecini[x][i].first});
            }
        }
    }

    for(int i = 0; i < k; i++){
        distante[s][i] = d[c[i]];
        distante[i][s] = d[c[i]];
    }
}

void presolve(){
    for(int t = 0; t < k; t++){
        dijkstra(t);
    }
}

void oldSolve(){
    vector<int> vx;

    for(int i = 1; i < k - 1; i++){
        vx.push_back(i);
    }

    int bestS = 100000000;

    do{
        int s = 0;

        s += distante[0][vx[0]];
        s += distante[vx[k - 3]][k - 1];

        for(int i = 0; i < k - 3; i++){
            s += distante[vx[i]][vx[i + 1]];
        }

        if(s < bestS){
            bestS = s;
        }
    }
    while(next_permutation(vx.begin(), vx.end()));

    printf("%d\n", bestS);
}

int dp[1<<16][17];

void solve(){
    for(int i = 0; i < (1 << k); i++){
        for(int j = 0; j < k; j++){
            dp[i][j] = inf;
        }
    }

    for(int i = 0; i < k; i++){
        dp[(1 << i)][i] = 0;
    }

    for(int i = 3; i < (1 << k); i++){
        for(int nod = 0; nod < k; nod++){
            if(i & (1 << nod)){
                for(int j = 0; j < k; j++){
                    if(i == j){
                        continue;
                    }
                    if(i & (1 << j)){
                        dp[i][nod] = min(dp[i][nod], dp[i ^ (1 << nod)][j] + distante[j][nod]);
                    }
                }
            }
        }
    }

    printf("%d", dp[(1 << (k)) - 1][k - 1]);
}

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

    citire();
    if(k != 2){
        presolve();
        solve();
    }
    else{
        dijkstra(0);
        printf("%d", d[n - 1]);
    }


    return 0;
}