Cod sursa(job #883130)

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

#define Nmax 2010
#define Kmax 20
#define Confmax 200000
#define INFI 0x3f3f3f3f

using namespace std;

int n, m, k, c[Kmax], best[Nmax], cv[Kmax][Kmax], sol[Confmax][Kmax];

struct muchie
{
    int nod;
    int cost;
};
vector <muchie> a[Nmax];
queue <int> q;

void preprop ()
{
    c[0] = 1;
    c[k + 1] = n;
    sort (c + 1, c + k + 1);
}

void citeste ()
{
    int i, x, y, cst;
    muchie r;
     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]);
    preprop();
    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)
{
    int j, nod, val;
    muchie r;
    q.push(sursa);
    best[sursa]=0;

    while (!q.empty())
    {
        nod = q.front();
        q.pop();
        int s = a[nod].size();

        for (j = 0; j < s; ++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 ()
{
    int j;
    for (j = 1; j <= n; ++j)
            best[j] = INFI;
}

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

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

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

        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 ()
{
    int i, j, m, conf, nod;
    ++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);
    ofstream h ("ubuntzei.out");
    h << sol[m - 1][k] << '\n';
   // freopen ("ubuntzei.out", "w", stdout);
   //printf ("%d\n", sol[m - 1][k]);
   h.close();
}

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