Cod sursa(job #1680979)

Utilizator BogauuuBogdan Ivancu Bogauuu Data 9 aprilie 2016 10:56:22
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.95 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#define nmax 2005
#define kmax 17
#define inf 1073741824
using namespace std;

struct muchie {
    int dist,nod;
};

vector <muchie> g[nmax];
int p[kmax],dist[nmax];
int ubuntzei[kmax+5][kmax+5];
int mat[1<<kmax][kmax];
int n,m,k;

struct cmp {
    bool operator() (const int &i, const int &j){
        return dist[i] > dist[j];
    }
};
priority_queue <int,vector <int>,cmp> heap;

inline muchie mkmuc(int nod,int dist) {
    muchie nou;
    nou.dist = dist;
    nou.nod = nod;
    return nou;
}

inline int min(int a,int b){
    if (a<b) return a;
    else return b;
}

void dijkstra(int s){
    vector <muchie> :: iterator it;
    for (int i=1;i <= n;i++) dist[i] = inf;
    dist[s] = 0;
    heap.push(s);
    while (!heap.empty()) {
        int u = heap.top();
        heap.pop();
        for (it = g[u].begin();it != g[u].end();it++) if (dist[(*it).nod] > dist[u] + (*it).dist) {
            dist[(*it).nod] = dist[u] + (*it).dist;
            heap.push((*it).nod);
        }
    }
}

int main(){
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    scanf("%d %d %d",&n,&m,&k);
    for (int i=1;i <= k;i++) scanf("%d",&p[i]);
    p[0] = 1;
    p[k+1] = n;
    k++;
    for (int i=1;i <= m;i++){
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        g[a].push_back(mkmuc(b,c));
        g[b].push_back(mkmuc(a,c));
    }
    for (int i=0;i <= k;i++){
        dijkstra(p[i]);
        for (int j=0;j <= k;j++) ubuntzei[i][j] = dist[p[j]];
    }
    for (int i=0;i<1<<(k+1);i++) for (int j=0;j <= k;j++) mat[i][j] = inf;
    mat[1][0] = 0;
    for (int i=0;i<1<<(k+1);i++) for (int j=0;j <= k;j++) if ((1<<j)&i)
        for (int ii=0;ii <= k;ii++) if ((1<<ii)&i)
            mat[i][j] = min(mat[i][j], mat[i ^ (1 << j)][ii] + ubuntzei[j][ii]);
    printf("%d\n", mat[(1<<(k+1))-1][k]);
    return 0;
}