Cod sursa(job #1638909)

Utilizator robertstrecheStreche Robert robertstreche Data 8 martie 2016 09:55:39
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.92 kb
#include <cstdio>
#include <bitset>
#include <vector>
#include <queue>

using namespace std;

const int KMAX=17;
const int NMAX=2005;
const int INF=1000000005;

queue <int>Q;
bitset <NMAX>in_Q;
vector <pair <int ,int > >V[NMAX];

int n,m,k,x,y,z;
int oras[KMAX],best[KMAX][1<<KMAX],dist[NMAX][NMAX];

void bellman_ford(int nod){
    for (int i=1;i<=n;i++)in_Q[i]=0;

    Q.push(nod);
    in_Q[nod]=1;
    while (!Q.empty()){
        int nodd=Q.front();
        in_Q[nodd]=0;
        Q.pop();

        for (auto it:V[nodd])
        if(dist[nod][nodd]+it.second<dist[nod][it.first]){
             dist[nod][it.first]=dist[nod][nodd]+it.second;
             dist[it.first][nod]=dist[nod][nodd]+it.second;
             if (!in_Q[it.first])Q.push(it.first);
             in_Q[it.first]=1;
        }
    }
}
int main()
{
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);

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

    scanf("%d",&k);
    for (int i=1;i<=k;i++)scanf("%d ",&oras[i]);

    for (int i=1;i<=n;i++)
       for (int j=1;j<=n;j++)if (i!=j)dist[i][j]=INF;

    for (;m;m--){
        scanf("%d %d %d\n",&x,&y,&z);

        V[x].push_back(make_pair(y,z));
        V[y].push_back(make_pair(x,z));
    }

    oras[0]=1,oras[++k]=n;
    for (int i=0;i<=k;i++)
         for (int l=1;l<(1<<k);l++)if ((1<<i)!=l)best[i][l]=INF;

    for (int i=1;i<=k;i++)bellman_ford(oras[i]);

    for (int l=1;l<(1<<k);l++)
        for (int i=1;i<=k && (1<<i)<=l;i++)
            if (l&(1<<i))for (int j=0;j<=k && (1<<j)<=l;j++)
                             if(i!=j && l&(1<<j))best[i][l]=(best[i][l]<best[j][l-(1<<i)]+dist[oras[i]][oras[j]]?best[i][l]:best[j][l-(1<<i)]+dist[oras[i]][oras[j]]);

    int sol=INF;
    for (int i=0;i<k;i++)if (best[i][(1<<k)-1]+dist[oras[i]][n]<sol)sol=best[i][(1<<k)-1]+dist[oras[i]][n];

    printf("%d",sol);

    fclose(stdin);
    fclose(stdout);
}