Cod sursa(job #2243577)

Utilizator Ruxandra985Nanu Ruxandra Laura Ruxandra985 Data 20 septembrie 2018 21:13:04
Problema Ubuntzei Scor 65
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.23 kb
#include <cstdio>
#include <bitset>
#include <vector>
#include <queue>
#include <iostream>
#define INF 1000000000

using namespace std;
bitset <2001> f;
vector < pair <int,int> > v[2001],w[20];
long long d[20][2001],sol[20][132000];
int k,ppoz,n,stop[20],fstop[2001],f2[20][132000],i,j,vecin,cost,stare,news,nod;
priority_queue <pair <int,int> > h;
priority_queue <pair <int,pair <int,int> > > h2;

void dijkstra_simplu(int nod){
    h.push(make_pair(0,nod));
    for (i=1;i<=n;i++){
        if (i!=nod)
            h.push(make_pair(-INF,i));
        d[ppoz][i]=INF;
    }
    d[ppoz][nod]=0;
    while (!h.empty()){
        nod=h.top().second;
        h.pop();
        while (f[nod]){
            if (h.empty())
                return;
            nod=h.top().second;
            h.pop();
        }
        f[nod]=1;
        for (vector <pair <int,int> > :: iterator it=v[nod].begin() ; it!=v[nod].end() ; it++){
            vecin=it->first;
            cost=it->second;
            if (!f[vecin] && cost+d[ppoz][nod]<d[ppoz][vecin]){
                d[ppoz][vecin]=d[ppoz][nod]+cost;
                h.push(make_pair(-d[ppoz][vecin],vecin));
            }
        }
    }
}

void dijkstra_complex (){
    h2.push(make_pair(0,make_pair(k-1,(1<<(k-2)))));
    for (i=1;i<=k;i++){
        for (j=0;j<=(1<<k)-1;j++){
            h2.push(make_pair(-INF,make_pair(i,j)));
            sol[i][j]=INF;
        }
    }
    sol[k-1][(1<<(k-2))]=0;
    while (!h2.empty()){
        nod=h2.top().second.first;
        stare=h2.top().second.second;
        h2.pop();
        while (f2[nod][stare]){
            if (h2.empty())
                return;
            nod=h2.top().second.first;
            stare=h2.top().second.second;
            h2.pop();
        }
        if (nod==k && stare==(1<<k)-1) /// AM GASIT SOLUTIA
            return ;
        f2[nod][stare]=1;
        for (vector <pair <int,int> > :: iterator it=w[nod].begin() ; it!=w[nod].end() ; it++){
            vecin=it->first;
            cost=it->second;
            news=(stare | (1<<(vecin-1)));
            if (!f2[vecin][news] && cost+sol[nod][stare]<sol[vecin][news]){
                sol[vecin][news]=sol[nod][stare]+cost;
                h2.push(make_pair(-sol[vecin][news],make_pair(vecin,news)));
            }
        }
    }
}
int main()
{
    FILE *fin=fopen ("ubuntzei.in","r");
    FILE *fout=fopen ("ubuntzei.out","w");
    int m,i,x,y,z,j;
    fscanf (fin,"%d%d%d",&n,&m,&k);
    for (i=1;i<=k;i++){
        fscanf (fin,"%d",&stop[i]);
        fstop[stop[i]]=1;
    }
    k+=2;
    stop[k-1]=1;
    stop[k]=n;
    for (i=1;i<=m;i++){
        fscanf (fin,"%d%d%d",&x,&y,&z);
        v[x].push_back(make_pair(y,z));
        v[y].push_back(make_pair(x,z));
    }
    for (i=0;i<k;i++){
        f.reset();
        ppoz=i;
        dijkstra_simplu (stop[i+1]);
        while (!h.empty())
            h.pop();
        for (j=1;j<=k;j++)
            if (j!=i+1 && d[ppoz][stop[j]]!=INF)
                w[i+1].push_back(make_pair(j,d[ppoz][stop[j]]));
    }
    // am creat noul graf pe care voi face tot dijkstra dar cu stari
    /// CHECKED
    dijkstra_complex ();
    fprintf (fout,"%lld",sol[k][(1<<k)-1]);
    return 0;
}