Cod sursa(job #1620713)

Utilizator grimmerFlorescu Luca grimmer Data 29 februarie 2016 12:08:40
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int NMAX = 2000;
const int INF = 0x3f3f3f3f;

struct Prior_queue{
    int node, dist;
};

class cmp{
    public:
    inline bool operator () (const Prior_queue a, const Prior_queue b){
        return a.dist > b.dist;
    }
};

priority_queue<Prior_queue, vector<Prior_queue>, cmp> pq;
vector<Prior_queue> G[NMAX + 5];
vector<int> friends;
int friends_dist[NMAX + 5][NMAX + 5], n, m, length[NMAX + 5], used[NMAX + 5], bkt_list[20], total = INF;

bool valid(int x){
    for(int i = 2; i < x; ++i)
        if(bkt_list[i] == bkt_list[x])
            return 1;
    return 0;
}

int verif_size(){
    int i, st = 1, dist = 0;
    for(i = 0; i < (int)friends.size(); ++i){
        dist += friends_dist[st][friends[i]];
        st = friends[i];
    }
    dist += friends_dist[st][n];
    return dist;
}

bool solutie(int x){
    if(x == (int)friends.size())
        return 1;
    return 0;
}

void bkt(int k){
    int i, current_dist = 0;
    for(i = 0; i < (int)friends.size(); ++i){
        bkt_list[k] = friends[i];

        if(valid(k) == 0){
            if(solutie(k - 1) == 1){
                current_dist = verif_size();

                if(current_dist < total){
                    total = current_dist;
                }
            }
            else{
                bkt(k + 1);
            }
        }
    }

}

void dijkstra(int node){
    memset(length, INF, sizeof(length));
    length[node] = 0;
    pq.push({node, 0});
    while(!pq.empty()){
        int frn = pq.top().node;
        pq.pop();

        for(int i = 0; i < (int)G[frn].size(); ++i){

            if(length[frn] + G[frn][i].dist < length[G[frn][i].node]){
                length[G[frn][i].node] = length[frn] + G[frn][i].dist;
                pq.push({G[frn][i].node, length[G[frn][i].node]});
            }

        }
    }
}

int main()
{
    int i, x, k, cost, u, v, j, curr_node, dest_node;
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    scanf("%d%d", &n, &m);
    scanf("%d", &k);

    for(i = 1; i <= k; ++i){
        scanf("%d", &x);
        friends.push_back(x);
    }

    for(i = 1; i <= m; ++i){
        scanf("%d%d%d", &u, &v, &cost);
        G[u].push_back({v, cost});
        G[v].push_back({u, cost});
    }

    dijkstra(1);
    if(k == 0){
        total = length[n];
    }

    for(i = 0; i < (int)friends.size(); ++i){
        friends_dist[1][friends[i]] = length[friends[i]];
    }

    for(i = 0; i < (int)friends.size(); ++i){
        curr_node = friends[i];
        dijkstra(curr_node);
        for(j = i + 1; j < (int)friends.size(); ++j){
            dest_node = friends[j];
            friends_dist[curr_node][dest_node] = friends_dist[dest_node][curr_node] = length[dest_node];
        }
        friends_dist[curr_node][n] = length[n];
    }

    bkt_list[1] = 1;
    bkt(2);
    printf("%d", total);


    return 0;
}