Cod sursa(job #1910928)

Utilizator matystroiaStroia Matei matystroia Data 7 martie 2017 18:50:20
Problema Ubuntzei Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.84 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

const int N=2001, K=15, INF=50000000;

typedef pair<int,int> ipair;

int n, m, k, d[N][1<<K], pri[N];
vector<pair<int,int>> ad[N];

struct el{int nod, dist, mask;};

class cmp
{
public:
    bool operator()(el a, el b)
    {
        return a.dist<b.dist;
    }
};

int main()
{
    fin>>n>>m>>k;
    fill_n(pri, n+1, -1);
    for(int i=0;i<k;++i)
    {
        int j;
        fin>>j;
        pri[j]=i;
    }

    for(int i=0;i<m;++i)
    {
        int x, y, z;
        fin>>x>>y>>z;
        ad[x].push_back(make_pair(y, z));
        ad[y].push_back(make_pair(x, z));
    }

    for(int i=1;i<=n;++i)
        for(int mask=0;mask<(1<<k);++mask)
            d[i][mask]=INF;

    priority_queue<el, vector<el>, cmp> pq;
    pq.push({1, 0, 0});
    d[1][0]=0;

    while(pq.size())
    {
        int nod=pq.top().nod;
        int mask=pq.top().mask;
        int dist=pq.top().dist;
        pq.pop();

        if(dist!=d[nod][mask])
            continue;

        for(auto v:ad[nod])
        {
            int vecin=v.first;
            int muchie=v.second;

            if(pri[v.first]==-1)
            {
                if(d[nod][mask]+v.second<d[v.first][mask])
                    d[v.first][mask]=d[nod][mask]+v.second, pq.push({v.first, d[v.first][mask], mask});
            }
            else
            {
                bool visited=mask&(1<<pri[vecin]);
                if(!visited&&d[nod][mask]+muchie < d[vecin][mask|(1<<pri[vecin])])
                    d[vecin][mask|(1<<pri[vecin])]=d[nod][mask]+muchie, pq.push({vecin, d[vecin][mask|(1<<pri[vecin])], mask|(1<<pri[vecin])});
            }
        }
    }

    fout<<d[n][(1<<k)-1];
    return 0;
}