Cod sursa(job #1086120)

Utilizator mirceadinoMircea Popoveniuc mirceadino Data 17 ianuarie 2014 19:03:11
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.2 kb
#include<algorithm>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>

using namespace std;

typedef pair<int,int> PII;
const int INF = 1<<30;
const int NMAX = 2005;
const int KMAX = 16;

struct cmp
{
    bool operator()(PII A,PII B)
    {
        return A.second>B.second;
    }
};

int N,M,K,KPow,sol;
int C[KMAX];
int Dist[KMAX][NMAX];
int DP[1<<KMAX][KMAX];
vector <PII> V[NMAX];
bitset <KMAX> B;
priority_queue <PII, vector<PII>, cmp> PQ;

void Dijkstra(int x,int Dist[])
{
    int i;
    vector <PII> :: iterator it;
    for(i=0; i<=NMAX; i++)
        Dist[i]=INF;
    Dist[x]=0;
    PQ.push(make_pair(x,0));
    for(; !PQ.empty();)
    {
        x=PQ.top().first;
        for(it=V[x].begin(); it!=V[x].end(); it++)
        {
            if(Dist[x]+it->second < Dist[it->first])
            {
                Dist[it->first]=Dist[x]+it->second;
                PQ.push(make_pair(it->first,Dist[it->first]));
            }
        }
        PQ.pop();
    }
}

int main()
{
    int i,j,k,a,b,c;
    vector <PII> :: iterator it;
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    scanf("%d%d",&N,&M);
    scanf("%d",&K);
    for(i=1; i<=K; i++)
        scanf("%d",&C[i]);
    for(; M; --M)
    {
        scanf("%d%d%d",&a,&b,&c);
        V[a].push_back(make_pair(b,c));
        V[b].push_back(make_pair(a,c));
    }
    for(i=1; i<=K; i++)
        Dijkstra(C[i],Dist[i]);
    KPow=1<<K;
    for(i=0; i<KPow; i++)
        for(j=0; j<=K; j++)
            DP[i][j]=INF;
    Dijkstra(1,Dist[0]);
    if(K==0)
    {
        printf("%d\n",Dist[0][N]);
        return 0;
    }
    for(i=1; i<=K; i++)
        DP[1<<(i-1)][i]=Dist[0][C[i]];
    for(i=1; i<KPow; i++)
    {
        B=i;
        for(j=1; j<=K; j++)
        {
            if(!B[j-1]) continue;
            for(k=1; k<=K; k++)
            {
                if(B[k-1] || j==k) continue;
                DP[i|(1<<(k-1))][k]=min(DP[i|(1<<(k-1))][k],DP[i][j]+Dist[j][C[k]]);
            }
        }
    }
    sol=INF;
    for(i=1; i<=K; i++)
        sol=min(sol,DP[KPow-1][i]+Dist[i][N]);
    printf("%d\n",sol);
    return 0;
}