Cod sursa(job #1607813)

Utilizator george_stelianChichirim George george_stelian Data 21 februarie 2016 16:58:45
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;

const int inf=1000000000;
struct edge
{
    int nod,c;
    edge(int nod1,int c1) {nod=nod1;c=c1;}
    bool operator <(const edge &aux) const
    {
        c>aux.c;
    }
};
vector<edge> g[2010];
priority_queue<edge> heap;
int v[20],d[2010][2010],din[1<<17][20],n;

void dijktra(int d[],int nod)
{
    for(int i=1;i<=n;i++) d[i]=inf;
    d[nod]=0;
    heap.push(edge(nod,0));
    while(!heap.empty())
    {
        int nod=heap.top().nod,c=heap.top().c;heap.pop();
        if(d[nod]!=c) continue;
        for(vector<edge>::iterator it=g[nod].begin();it!=g[nod].end();it++)
            if(d[it->nod]>d[nod]+it->c)
            {
                d[it->nod]=d[nod]+it->c;
                heap.push(edge(it->nod,d[it->nod]));
            }
    }
}

int main()
{
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);
    int m,k,x,y,c,sol=inf;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<k;i++) scanf("%d",&v[i]);
    v[k]=1;
    v[k+1]=n;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&c);
        g[x].push_back({y,c});
        g[y].push_back({x,c});
    }
    for(int i=0;i<=k+1;i++) dijktra(d[v[i]],v[i]);
    int lim=1<<k;
    for(int i=1;i<lim;i++)
        for(int j=0;j<k;j++) din[i][j]=inf;
    for(int i=0;i<k;i++) din[1<<i][i]=d[1][v[i]];
    for(int i=1;i<lim;i++)
        for(int j=0;j<k;j++)
            if(i&(1<<j) && din[i][j]<inf)
                for(int q=0;q<k;q++)
                    if((i&(1<<q))==0) din[i|(1<<q)][q]=min(din[i|(1<<q)][q],din[i][j]+d[v[j]][v[q]]);
    for(int i=0;i<k;i++)
        sol=min(sol,din[lim-1][i]+d[v[i]][n]);
    if(k==0) sol=d[1][n];
    printf("%d",sol);
    return 0;
}