Cod sursa(job #612721)

Utilizator vendettaSalajan Razvan vendetta Data 9 septembrie 2011 20:45:08
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
#include <cstdio>
#include <vector>
#include <queue>
#define nmax 2001
#define kmax 17
#define inf 1<<30

using namespace std;

typedef vector<pair<int,int> >::iterator it;

vector< pair<int, int> > gf[nmax];
vector<int> imp; // vectorul ce va contine localitatile prin care va trebui sa treaca drumul de cost minim;
int dp[(1<<kmax)][kmax], ap[kmax][kmax];
bool viz[(1<<kmax)][kmax];
int n, m, k;

void citeste(){

    freopen("ubuntzei.in", "r", stdin);

    scanf("%d %d", &n, &m);

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

    for(int i=1; i<=m; i++){
        int x, y, c;
        scanf("%d %d %d", &x, &y, &c);
        gf[x].push_back(make_pair(y,c));
        gf[y].push_back(make_pair(x,c));
    }

    fclose(stdin);

}

vector<int> bf(int x){

    vector<int> d(n+1, inf);
    vector<bool> vz(n+1, 0);
    queue<int> q;

    q.push(x);
    d[x] = 0;
    vz[x] = 1;
    for(; q.size(); q.pop()){
        int nod = q.front();
        vz[nod]=0;
        for(it i=gf[nod].begin(); i!=gf[nod].end(); i++){
            int vecin = i->first;
            int cost = i->second;
            if (d[vecin] > d[nod] + cost){
                d[vecin] = d[nod] + cost;
                if (vz[vecin] == 0){
                    vz[vecin] == 1;
                    q.push(vecin);
                }
            }
        }
    }
    return d;

}

void initializeaza(){

    imp.push_back(n);
    imp.insert(imp.begin(), 1);
    k += 2;

    for(unsigned i=0; i<imp.size(); i++){
        vector<int> d = bf(imp[i]);
        for(unsigned j=0; j<imp.size(); j++)
            ap[i][j] = d[imp[j]];
    }

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

}

void rezolva(){

    queue< pair<int,int> > q;
    dp[1][0] = 0;
    viz[1][0] = 1;
    q.push(make_pair(1,0));

    for(; q.size(); q.pop()){
        int nod = (q.front()).first;
        int stare = (q.front()).second;
        viz[nod][stare]=0;
        for(int i=0; i<k; i++){
            if (((nod >> i)&1) == 0 && stare != i && dp[nod + (1<<i)][i] > dp[nod][stare] + ap[stare][i]){
                dp[nod + (1<<i)][i] = dp[nod][stare] + ap[stare][i];
                if (viz[nod + (1<<i)][i] == 0){
                    viz[nod + (1<<i)][i] = 1;
                    q.push(make_pair(nod + (1<<i), i));
                }
            }
        }
    }

}

void scrie(){
    int n = 1;
    freopen("ubuntzei.out", "w", stdout);
    printf("%d", dp[(1<<k)-1][k-1]);
    //printf("%d", n);
    fclose(stdout);

}

int main(){

    citeste();
    initializeaza();
    rezolva();
    scrie();

}