Cod sursa(job #2942650)

Utilizator LuxinMatMatasaru Luxin Gabriel LuxinMat Data 19 noiembrie 2022 22:27:42
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.14 kb
#include<fstream>
#include<vector>
#include<queue>
#include<strings.h>
using namespace std;

ifstream cin("ubuntzei.in");
ofstream cout("ubuntzei.out");

const int NMAX = 2000;
const int INF = 1e9;

vector<pair<int, int>> v[NMAX+1], v2[16]; /// vecin, cost
vector<int> city;
int dp[19][1<<19], v1[17][17], ct[NMAX+1];
int n;

void dijkstra(int nr, int pos)
{
    priority_queue<pair<int, int>> pq; ///cost, vecin
    bool viz[NMAX+1];

    memset(viz, 0, sizeof(viz));
    for(int i=1; i<=n; i++)
        ct[i] = INF;

    pq.push({0, nr});
    ct[nr] = 0;
    while(!pq.empty())
    {
        pair<int, int> elem = pq.top();
        pq.pop();
        int nod = elem.second;
        int cost = -elem.first;
        if(!viz[nod])
        {
            viz[nod] = 1;
            for(int i=0; i<city.size(); i++)
            {
                if(city[i] == nod)
                {
                    v2[pos+1].push_back({i+1, cost});
                    v1[pos+1][i+1] = cost;
                }
            }
            if(nod == 1)
            {
                v2[pos+1].push_back({0, cost});
                v2[0].push_back({pos+1, cost});
                v1[0][pos+1] = cost;
                v1[pos+1][0] = cost;
            }
            if(nod == n)
            {
                //v2[nr].push_back({n, cost});
                v1[16][pos+1] = cost;
                v1[pos+1][16] = cost;
            }
            for(auto elem2: v[nod])
            {
                int vecin = elem2.first;
                int pret = elem2.second;
                if(!viz[vecin] && ct[vecin] > ct[nod]+pret)
                {
                    ct[vecin] = ct[nod]+pret;
                    pq.push({-(ct[nod]+pret), vecin});
                }
            }
        }
    }
}

int main()
{
    int m, k;
    cin>>n>>m>>k;
    for(int i=1; i<=k; i++)
    {
        int x;
        cin>>x;
        city.push_back(x);
    }
    for(int i=1; i<=m; i++)
    {
        int x, y, c;
        cin>>x>>y>>c;
        v[x].push_back({y, c});
        v[y].push_back({x, c});
    }
    for(int i=0; i<17; i++)
        for(int j=0; j<=17; j++)
            v1[i][j] = 0;
    for(int i=0; i<city.size(); i++)
        dijkstra(city[i], i);

    for(int mask=1; mask < 1<<16; mask++)
        for(int nod=0; nod <= k; nod++)
            dp[nod][mask] = INF;

    dp[0][1] = 0;
    int minim = INF;
    for(int mask=1; mask < 1<<16; mask++)
        for(int nod=0; nod <= k; nod++)
            if(dp[nod][mask] != INF)
            {
                //cout<<nod<<" "<<mask<<" "<<dp[nod][mask]<<'\n';
                if(mask == (1<<(k+1))-1 && v1[nod][16])
                    minim = min(minim, dp[nod][mask] + v1[nod][16]);
                for(auto x : v2[nod])
                {
                    int vecin = x.first;
                    int cost = x.second;
                    if(!(mask & (1<<vecin)))
                    {
                        dp[vecin][mask ^ (1<<vecin)] = min(dp[vecin][mask ^ (1<<vecin)], dp[nod][mask] + cost);
                    }
                }
            }
    cout<<minim;
    return 0;
}