Cod sursa(job #1911878)

Utilizator matystroiaStroia Matei matystroia Data 7 martie 2017 22:07:11
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.3 kb
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
#include <functional>
#include <bitset>
using namespace std;

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

const int N=2005, K=18, INF=0x3F3F3F3F;

typedef pair<int,int> ipair;

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

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

vector<int> dijkstra(int src, vector<ipair>* ad)
{
    vector<int> d(n+1, INF);
    d[src]=0;

    priority_queue<ipair> pq;
    pq.push(make_pair(0, src));

    while(!pq.empty())
    {
        int nod=pq.top().second;
        int dist=-pq.top().first;
        pq.pop();

        if(dist>d[nod]) continue;

        for(vector<ipair>::iterator it=ad[nod].begin(); it!=ad[nod].end(); ++it)
        {
            int v=(*it).first;
            int cost=(*it).second;
            if(d[nod]+cost<d[v])
            {
                d[v]=d[nod]+cost;
                pq.push(make_pair(-d[v], v));
            }
        }
    }
    return d;
}

int dijkstra_k(int src, int sink, int knodes, vector<ipair>* adk)
{
    memset(dt, INF, sizeof dt);
    dt[src][1<<src]=0;

    priority_queue<pair<int, pair<int,int>>> pq;
    pq.push(make_pair(0, make_pair(src, 1<<src)));

    while(!pq.empty())
    {
        int nod=pq.top().second.first;
        int dist=-pq.top().first;
        int mask=pq.top().second.second;
        pq.pop();

        if(dist>dt[nod][mask]) continue;

        for(vector<ipair>::iterator it=adk[nod].begin(); it!=adk[nod].end(); ++it)
        {
            int v=(*it).first;
            int cost=(*it).second;

            if(!(mask&(1<<v)))
            {
                int new_mask=mask|(1<<v);
                if(dt[nod][mask]+cost<dt[v][new_mask])
                {
                    dt[v][new_mask]=dt[nod][mask]+cost;
                    pq.push(make_pair(-dt[v][new_mask], make_pair(v, new_mask)));
                }
            }
        }
    }
    return dt[sink][(1<<knodes)-1];
}

int main()
{
    fin>>n>>m>>k;

    vector<int> subset(k), idx(n+1);
    bitset<N> inSet;

    for(int i=0;i<k;++i)
    {
        int j;
        fin>>j;
        subset[i]=j;
        idx[j]=i;
        inSet[j]=true;
    }

    subset.push_back(1), idx[1]=(int)subset.size()-1, inSet[1]=true;
    subset.push_back(n), idx[n]=(int)subset.size()-1, inSet[n]=true;

    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));
    }

    vector<int> d;
    d=dijkstra(1, ad);

    for(size_t i=0;i<d.size();++i)
    {
        if(inSet[i])
        {
            if((int)i!=1)
                adk[idx[1]].push_back(make_pair(idx[i], d[i]));
        }
    }

    if(k>0)
    {
        for(size_t i=0;i<subset.size();++i)
            if(subset[i]!=1&&subset[i]!=n)
            {
                d=dijkstra(subset[i], ad);
                for(size_t j=0;j<d.size();++j)
                    if(inSet[j]&&subset[i]!=(int)j)
                        adk[i].push_back(make_pair(idx[j], d[j]));
            }

        int sol=dijkstra_k(idx[1], idx[n], subset.size(), adk);
        fout<<sol<<'\n';
    }
    else
        fout<<d[n]<<'\n';

    return 0;
}