Cod sursa(job #1075343)

Utilizator lukkerLiNoimi Semain lukker Data 8 ianuarie 2014 21:18:13
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.87 kb
#include <cstring>
#include <vector>
#include <fstream>
using namespace std;
 
#define maxk 17
#define maxn 2010
#define inf 1000000000
 
int n, m, k, a, b, c;
int d[1<<maxk][maxk];
int dist[maxk][maxk], poz[maxk], conf[maxk];
int dmin[maxn], f[maxn], q[maxn];
vector<int> v[maxn], w[maxn];
 
void bellmanford(int start, int where) {
    int q0=1, nod, fiu;
 
    memset(f, 0, sizeof(f));
 
    q[q0]=start;
    for(int i=1; i<=n; ++i)
        dmin[i]=inf;
 
    dmin[start]=0;
    f[start]=1;
    for(int i=1; i<=q0; ++i) {
        nod=q[i%n];
        f[nod]=0;
        for(int j=0; j<(int)v[nod].size(); ++j) {
            fiu=v[nod][j];
            if(dmin[fiu]>dmin[nod]+w[nod][j]) {
                dmin[fiu]=dmin[nod]+w[nod][j];
                if(f[fiu]==0) {
                    ++q0;
                    q[q0%n]=fiu;
                    f[fiu]=1;
                }
            }
        }
    }
    for(int i=0; i<k; ++i)
        dist[where][i]=dmin[poz[i]];
}
 
int main() {
    ifstream in("ubuntzei.in");
    ofstream out("ubuntzei.out");
 
    in>>n>>m>>k;
    for(int i=1; i<=k; ++i) in>>poz[i];
    poz[++k]=n;
    ++k;
    for(int i=1; i<=m; ++i) {
        in>>a>>b>>c;
        v[a].push_back(b);
        v[b].push_back(a);
        w[a].push_back(c);
        w[b].push_back(c);
    }
 
    poz[0]=1;
    for(int i=0; i<k; ++i)
        bellmanford(poz[i], i);
 
    d[1][0]=0;
 
    for(int i=0; i<(1<<k); ++i) {
        for(int j=0; j<k; ++j)
            conf[j]=((i>>j)&1);
        for(int j=0; j<k; ++j) {
            if(i!=1 || j!=0) d[i][j]=inf;
            if(conf[j]==0) continue;
            for(int l=0; l<k; ++l) {
                if(l==j || conf[l]==0) continue;
                d[i][j]=min(d[i][j], d[i-(1<<j)][l]+dist[j][l]);
            }
        }
    }
 
    out<<d[(1<<k)-1][k-1]<<endl;;
    return 0;
}