Cod sursa(job #851409)

Utilizator unsilviuContvechidontdeactivatepls unsilviu Data 9 ianuarie 2013 22:48:49
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <set>
#include <utility>
#define ff first
#define ss second
#define mp make_pair

#define BIG 0x7fffffff


using namespace std;

vector<pair <int,int> > grf[2001];
int obg[16],n,graff[17][33000],k;
int dmin[17][17];



vector <int> dijkstra(int start) {
    vector <int> v(n+1, BIG);
    pair<int,int> p,x;
    v[start] = 0;
    set< pair<int,int> > frontier;
    p.ff = 0; p.ss = start;
    frontier.insert(p);
    while (!frontier.empty()) {
        p = *frontier.begin();
        frontier.erase(frontier.begin());
        for (int i=0; i<grf[p.ss].size(); i++) {
            if (p.ff + grf[p.ss][i].ff < v[grf[p.ss][i].ss] ) {
                v[grf[p.ss][i].ss] = p.ff + grf[p.ss][i].ff;
                x.ff = v[grf[p.ss][i].ss];
                x.ss = grf[p.ss][i].ss;
                frontier.insert(x);
            }
        }
    }
    return v;
}

void dike() {                  // dis = a.ff.ff node = a.ff.ss id = a.ss
    int bit;
    pair< pair<int,int>,int> a,b;
    set<pair< pair<int,int>,int> > frontier;
    a.ff.ss = a.ss = a.ff.ff = 0;
    frontier.insert(a);

    while (!frontier.empty()) {
        a = *frontier.begin();
        frontier.erase(frontier.begin());
        if (a.ff.ff == ((1<<(k))-1) ) {
            if (a.ff.ff+dmin[a.ff.ss][k+1]<graff[k+1][(1<<(k))-1])
                graff[k+1][(1<<(k))-1] = a.ff.ff+dmin[a.ff.ss][k+1];
        }

        else {
        for (int i=1; i<=k; i++)
            if (i!=a.ff.ss) {
                bit = a.ss;
                if (((1<<(i-1))|bit)!=bit)
                    bit += (1<<(i-1));

                if (a.ff.ff+dmin[a.ff.ss][i]<graff[i][bit]) {
                    graff[i][bit] = a.ff.ff+dmin[a.ff.ss][i];
                    b.ff.ss = i;
                    b.ss = bit;
                    b.ff.ff = graff[i][bit];
                    frontier.insert(b);
                }

            }


        }


    }
}
int main() {
    int m,i,j,a,b,d,l;
    ifstream in("ubuntzei.in");
    ofstream out("ubuntzei.out");
    in>>n>>m;
    in>>k;
    for (i=1; i<=k; i++)
        in>>obg[k];

    for (i=1; i<=m; i++) {
        in>>a>>b>>d;
        grf[a].push_back( mp (d,b));
        grf[b].push_back( mp (d,a));
    }

    vector <int> dist;
    dist = dijkstra(1);
    if (k==0)
        out<<dist[n]<<'\n';
    else {
    for (i=1; i<= k; i++)
        dmin[0][i] = dmin[i][0] = dist[obg[i]];

    dmin[0][k+1] = dmin[k+1][0] = dist[n];

    for (i=1; i<=k; i++) {
        dist = dijkstra(obg[i]);
        for (j = i+1; j<=k; j++)
            dmin[i][k] = dmin[k][i] = dist[obg[j]];
        dmin[i][k+1] = dist[n];
    }

    for (i=1; i<=(k+1); i++)
        for (j=0; j<= (1<<(k))-1; j++)
            graff[i][j] = BIG;
    dike();

    out<<graff[k+1][(1<<(k))-1]<<'\n';

    }

    out.close();
    return 0;
}