Cod sursa(job #1538916)

Utilizator tudi98Cozma Tudor tudi98 Data 29 noiembrie 2015 23:55:01
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <fstream>
#include <vector>
#include <queue>
#include <utility>
#include <cstring>
using namespace std;
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define Nmax 2000
#define inf 1000000001

int n,m,k;

struct comp {
    bool operator()(const pii& a, const pii& b) {
        return a.second > b.second;
    }
};

vector<pii> G[Nmax+1];
priority_queue<pii,vector<pii>,comp> Q;
int dist[Nmax+1];
int c[20][20],C[20][1<<18];
vector<int> v;

void Dijkstra(int node,int id)
{
    for (int i = 1; i <= n; i++)
        dist[i] = inf;
    dist[node] = 0;
    Q.push(mp(node,0));
    while (!Q.empty())
    {
        pii u = Q.top(); Q.pop();
        for (vector<pii>::iterator it = G[u.first].begin(); it != G[u.first].end(); it++)
            if (dist[it->first] > u.second + it->second)
            {
                dist[it->first] = u.second + it->second;
                Q.push(mp(it->first,dist[it->first]));
            }
    }
    for (int i = 0; i <= k + 1; i++)
        c[id][i] = min(c[id][i],dist[v[i]]);
}

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

    fin >> n >> m >> k;
    v.push_back(1);
    for (int i = 1; i <= k; i++)
    {
        int x;
        fin >> x;
        v.push_back(x);
    }
    v.push_back(n);

    int x,y,z;
    for (int i = 1; i <= m; i++)
    {
        fin >> x >> y >> z;
        G[x].pb(mp(y,z));
        G[y].pb(mp(x,z));
    }

    for (int i = 0; i <= k + 1; i++)
        for (int j = 0; j <= k + 1; j++)
            c[i][j] = inf;

    for (int i = 0; i <= k + 1; i++)
        Dijkstra(v[i],i);

    // gasim ciclul hamiltonian de cost minim in graful format doar din nodurile
    // 1 , cele k orase , n

    k += 2;
    for (int i = 0; i < 1<<k; i++)
        for (int j = 0; j < k; j++)
            C[j][i] = inf;

    C[0][1] = 0;
    for (int i = 0; i < 1<<k; i++)
        for (int j = 0; j < k; j++)
            if (i & (1<<j))
                for (int h = 0; h < k; h++)
                    if (i & (1<<h) && h != j)
                        C[j][i] = min (C[j][i], C[h][i ^ (1<<j)] + c[h][j]);

    fout << C[k-1][(1<<k)-1] << "\n";
}