Cod sursa(job #933045)

Utilizator PatrikStepan Patrik Patrik Data 29 martie 2013 15:48:05
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.45 kb
    #include<cstdio>
    #include<vector>
    #include<queue>
    using namespace std;
    #define NMAX 2001
    #define KMAX 16
    #define pb push_back
    #define mp make_pair
    #define INF 1000000001
    int N , M , K ,C[KMAX], d[1<<KMAX][KMAX] , path[KMAX][NMAX] , v[NMAX] , sol;
    vector<pair<int,int> >G[NMAX];
    queue<int>Q;

    void citire();
    void solve();
    void b_ford(int nod,int v[]);
    void tipar();

    int main()
    {
        citire();
        solve();
        tipar();
        return 0;
    }

    void citire()
    {
        int x , y , cost;
        freopen("ubuntzei.in" , "r" , stdin );
        scanf("%d%d%d" , &N , &M , &K );
        for(int i = 0 ; i < K ; ++i )
            scanf("%d" , &C[i]);
        for(;M;M--)
        {
            scanf("%d%d%d" , &x ,&y , &cost);
            G[x].pb(mp(y,cost));
            G[y].pb(mp(x,cost));
        }
    }

    void b_ford(int n , int v[])
    {
        for(int i = 1 ; i <= N ; ++i )v[i] = INF;
        v[n] = 0;
        for(Q.push(n);!Q.empty();Q.pop())
        {
            int nod = Q.front();
            for(int j = 0 ; j < (int)G[nod].size() ; ++j)
                if(v[G[nod][j].first] > v[nod]+G[nod][j].second)
                {
                    v[G[nod][j].first] = v[nod]+G[nod][j].second;
                    Q.push(G[nod][j].first);
                }
        }
    }

    void solve()
    {
        b_ford(1,v);
        if(K==0)
        {
            sol = v[N];
            return ;
        }
        for(int i = 0 ; i < K ; ++i )
            b_ford(C[i],path[i]);
        for(int i = 0 ; i < K ; ++i )
            d[1<<i][i] = v[C[i]];
        for(int i = 1 ; i < (1<<K) ; ++i)
        {
            for(int j = 0 ; j < K ; ++j )
            {
                if(i==1<<j)continue;
                if(i&(1<<j))
                   {
                       d[i][j] = INF;
                       for(int p = 0 ; p < K ; ++p )
                       {
                           if(p==j)continue;
                           if(i&(1<<p))
                           d[i][j] = min(d[i][j],d[i-(1<<j)][p]+path[p][C[j]]);
                       }
                   }
            }
        }
        sol = INF;
        for(int i = 0 ; i < K ; ++i)
            sol = min(sol,d[(1<<K)-1][i]+path[i][N]);
    }

    void tipar()
    {
        freopen("ubuntzei.out" , "w" , stdout );
        printf("%d\n" , sol);
    }