Cod sursa(job #2499759)

Utilizator Senth30Denis-Florin Cringanu Senth30 Data 26 noiembrie 2019 18:29:26
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <bits/stdc++.h>
#define MAX 131072

using namespace std;
const int NMAX = 2010;

FILE *IN;

struct edge{
    int x, cost;
};

vector <edge> edges[NMAX], mch[20];
queue <int> nodes;

int N, M, K;
int dp[(1 << 18) + 10][20];
int point[20], ans[NMAX];

int pos, sign;
char f[MAX];

inline void Read(int &nr){
    sign = 0;
    nr = 0;
    while(f[pos] < '0' || f[pos] > '9'){
        if(f[pos] == '-') sign = 1;
        pos++;
        if(pos == MAX)
            fread(f, MAX, 1, IN), pos = 0;
    }
    while(f[pos] >= '0' && f[pos] <= '9'){
        nr = 10 * nr + f[pos++] - '0';
        if(pos == MAX)
            fread(f, MAX, 1, IN), pos = 0;
    }
    if(sign) nr =- nr;
}

void read(){
    Read(N); Read(M); Read(K);
    point[1] = 1; K++;
    for(int i = 2; i <= K; i++)
        Read(point[i]);
    point[++K] = N;
    int a, b, C;
    for(int i = 1; i <= M; i++){
        Read(a); Read(b); Read(C);
        edges[a].push_back({b, C});
        edges[b].push_back({a, C});
    }
}

void bellman_ford(int y){
    for(int i = 1; i <= N; i++)
        ans[i] = 2e9;
    ans[y] = 0;
    nodes.push(y);
    while(!nodes.empty()){
        int node = nodes.front();
        nodes.pop();
        for(int i = 0; i < edges[node].size(); i++){
            int x = edges[node][i].x;
            int c = edges[node][i].cost;
            if(ans[x] > ans[node] + c){
                ans[x] = ans[node] + c;
                nodes.push(x);
            }
        }
    }
}

int main(){

    IN = fopen("ubuntzei.in", "r");
    freopen("ubuntzei.out", "w", stdout);

    read();

    for(int i = 1; i <= K; i++){
        bellman_ford(point[i]);
        for(int j = 1; j <= K; j++)
            if(i != j)
                mch[i].push_back({j, ans[point[j]]});
    }

    for(int i = 1; i <= (1 << K) - 1; i++)
        for(int j = 1; j <= K; j++)
            dp[i][j] = (1 << 28);
    dp[1][1] = 0;

    for(int l = 1; l <= (1 << K) - 1; l++)
        if(l & 1){
            for(int i = 1; i <= K; i++)
                if(((1 << i - 1) & l) && dp[l][i] != (1 << 28))
                    for(int j = 0; j < mch[i].size(); j++){
                        edge e = mch[i][j];
                        dp[l + (1 << e.x - 1)][e.x] = min(dp[l + (1 << e.x - 1)][e.x], dp[l][i] + e.cost);
                    }
        }

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

    return 0;
}