Cod sursa(job #1011201)

Utilizator mvcl3Marian Iacob mvcl3 Data 16 octombrie 2013 16:00:44
Problema Ubuntzei Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.21 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
#include <string.h>
#include <algorithm>
#define IN "ubuntzei.in"
#define OUT "ubuntzei.out"
#define MAX_N 205
#define MAX_K 15
#define oo 10000

using namespace std;

ifstream f(IN);
ofstream g(OUT);

int N, M, K, u, v, cost;
int dist[MAX_N][1 << MAX_K], rf[MAX_N][MAX_N];;

bitset< (1 << MAX_K) > inque[MAX_N];
queue < pair < int, int > > Q;
vector < int > adj[MAX_N], subset, idxSubset;
bitset < MAX_N > inSubset;

inline void READ_DATA()
{
        f >> N >> M >> K;

        subset.resize(K);
        idxSubset.resize(N);
        idxSubset.assign(idxSubset.size(), -1);

        for (int i = 0; i < K; ++ i)
        {
                f >> u; -- u;
                subset[i] = u;
                idxSubset[u] = i;
                inSubset[u] = true;
        }

        for (int i = 0; i < M; ++ i)
        {
            f >> u >> v >> cost;
            -- u, -- v;
            rf[u][v] = rf[v][u] = cost;
        }
}

inline void RF()
{
    for (int k = 0; k < N; ++ k)
        for (int i = 0; i < N; ++ i)
            for (int j = 0; j < N; ++ j)
                rf[i][j] = min(rf[i][j], rf[i][k] + rf[k][j]);
}
void SOLVE()
{
    if (K > 0)
    {
        for (int i = 0; i < N; ++ i)
            for (int j = i + 1; j < N; ++ j)
                if ((inSubset[i] || !i || i == N - 1) && (inSubset[j] || !j || j == N - 1))
                {
                    adj[i].push_back(j);
                    adj[j].push_back(i);
                }

        memset(dist, oo, sizeof(dist));
        dist[0][0] = 0;
        Q.push(make_pair(0, 0)), inque[0][0] = true;

        while (!Q.empty())
        {
            int u = Q.front().first;
            int s = Q.front().second;
            Q.pop();
            inque[u][s] = false;

            for (vector <int>::iterator it = adj[u].begin(); it != adj[u].end(); ++ it)
            {
                int v = *it;
                if (!inSubset[v])
                {
                    if (dist[v][s] > dist[u][s] + rf[u][v])
                    {
                        dist[v][s] = dist[u][s] + rf[u][v];
                        if (inque[v][s] == false)
                        {
                            Q.push(make_pair(v, s));
                            inque[v][s] = true;
                        }
                    }
                }
                else
                if (!(s & (1 << idxSubset[v])))
                {
                    int t = s | (1 << idxSubset[v]);
                    if (dist[v][t] > dist[u][s] + rf[u][v])
                    {
                        dist[v][t] = dist[u][s] + rf[u][v];
                        if (inque[v][t] == false)
                        {
                            Q.push(make_pair(v, t));
                            inque[v][t] = true;
                        }
                    }
                }
            }
        }

        int sink = N - 1;
        int conf = (1 << subset.size()) - 1;
        g << dist[sink][conf] << "\n";
    }
    else
        g << rf[0][N - 1] << "\n";

}

int main(void)
{
    memset(rf, oo, sizeof(rf));
    for (int i = 0; i < N; ++ i)
            rf[i][i] = 0;

    READ_DATA();
    RF();
    SOLVE();

    g.close();
    return 0;
}