Cod sursa(job #1911766)

Utilizator matystroiaStroia Matei matystroia Data 7 martie 2017 21:45:45
Problema Ubuntzei Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 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=5000000;

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

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

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

    priority_queue<ipair, vector<ipair>, greater<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(ipair mu:ad[nod])
        {
            int v=mu.first;
            int cost=mu.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)
{
    for(int i=0;i<knodes;++i)
        for(int mk=0;mk<(1<<knodes);++mk)
            dt[i][mk]=INF;

    dt[src][1<<src]=0;

    priority_queue<el, vector<el>, cmp> pq;
    pq.push({src, 0, 1<<src});

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

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

        for(ipair mu:adk[nod])
        {
            int v=mu.first;
            int cost=mu.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({v, dt[v][new_mask], 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(int i=0;i<d.size();++i)
    {
        if(inSet[i])
        {
            if(i!=1)
                adk[idx[1]].push_back(make_pair(idx[i], d[i]));
        }
    }

    if(k>0)
    {
        for(int i=0;i<subset.size();++i)
            if(subset[i]!=1&&subset[i]!=n)
            {
                d=dijkstra(subset[i], ad);
                for(int j=0;j<d.size();++j)
                    if(inSet[j]&&subset[i]!=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;
}