Cod sursa(job #883105)

Utilizator andreea29Iorga Andreea andreea29 Data 19 februarie 2013 18:47:07
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
#include<cstdio>
//#include<fstream>
#include<vector>
#include<queue>
#include<algorithm>

#define Nmax 2050
#define Kmax 25
#define Confmax 200000
#define INFI 1000000050

using namespace std;

int n, m, k, c[Kmax], best[Nmax], cv[Kmax][Kmax], sol[Confmax][Kmax], i, x, y, cst, nod, val, confp, mn = INFI, conf, j;
struct muchie
{
    int nod;
    int cost;
};
muchie r;
vector <muchie> a[Nmax];
queue <int> q;

void citeste ()
{
    // ifstream f("ubuntzei.in");
   // ofstream h("ubuntzei.out");
    //f >> n >> m;
    //f >> k;
    freopen ("ubuntzei.in", "r", stdin);
    scanf ("%d %d", &n, &m);
    scanf ("%d", &k);
    for (i = 1; i <= k; ++i)
      //  f >> c[i];
      scanf ("%d", &c[i]);
    c[0] = 1;
    c[k + 1] = n;
    sort (c + 1, c + k + 1);
    for (i = 1; i <= m; ++i)
    {
        //f >> x >> y >> cst;
        scanf ("%d %d %d", &x, &y, &cst);
        r.nod = y;
        r.cost = cst;
        a[x].push_back(r);
        r.nod = x;
        a[y].push_back(r);
    }
    //f.close();
}

void dmin(int sursa)
{
    q.push(sursa);
    best[sursa]=0;

    while (!q.empty())
    {
        nod = q.front();
        q.pop();

        for (j = 0; j < a[nod].size(); ++j)
        {
            r = a[nod][j];
            val = r.cost + best[nod];

            if (val < best[r.nod])
            {
                q.push(r.nod);
                best[r.nod] = val;
            }
        }
    }
}

void init ()
{
    for (j = 1; j <= n; ++j)
            best[j] = INFI;
}

void calc (int i)
{
    for (j = 0; j <= k + 1; ++j)
            if (j != i && !cv[j][i])
                cv[j][i] = cv[i][j] = best[c[j]];
}

void rezolva ()
{
    for (i = 0; i <= k + 1; ++i)
    {
        init ();
        dmin(c[i]);
        calc (i);
    }
}

int recurenta(int conf, int nod)
{
    mn = INFI;
    if (conf && (1<<nod) != 0)
    {
        confp = conf^(1<<nod);

        for (i = 0; i <= k; ++i)
            if (cv[i][nod])
            {
                val = sol[confp][i] + cv[i][nod];
                mn = min(mn, val);
            }
            return mn;
    }
    else
        return INFI;
}

void solutie ()
{
    ++k;
    m = (1 << (k + 1));
    for (i = 1; i <= m; ++i)
        for (j = 0; j <= k; ++j)
            sol[i][j] = INFI;

    sol[1][0]=0;

    for (conf = 3; conf < m; ++conf)
        for (nod = 0; nod <= k; ++nod)
            sol[conf][nod] = recurenta(conf, nod);

    freopen ("ubuntzei.out", "w", stdout);
    printf ("%d\n", sol[m - 1][k]);
   // h<<sol[m - 1][k]<<"\n";
  //  h.close();
}

int main()
{
    citeste ();
    rezolva ();
    solutie ();
    return 0;
}