Cod sursa(job #1263021)

Utilizator sebinechitasebi nechita sebinechita Data 13 noiembrie 2014 20:34:18
Problema Algoritmul lui Dijkstra Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.44 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
ifstream fin("boom.in");
ofstream fout("boom.out");
#define pb push_back
#define mp make_pair
#define cout fout

int cost[52], dist[(1<<20)+2];
int x, y;
typedef vector <pair< int, int > > :: iterator iter;
vector <int> v[52], X;
vector <pair < int, int > > G[(1<<20)+2];
pair <int, int > Q[(1<<20)+2];
pair < int , int > p[(1<<20)+2];

int main()
{
    int n, m, i, k, dr, j, nr, r;
    fin>>n>>m;
    for(i=1;i<=m;i++)
    {
        fin>>cost[i];
        fin>>x;
        v[i].pb(x);
        while(x--)
        {
            fin>>y;
            v[i].pb(y);
        }
    }
    for(k=1;k<(1<<n);k++)
    {
        for(i=1;i<=m;i++)
        {
            y=k;
            for(j=1;j<=v[i][0];j++)
            {
                if(y&(1<<(v[i][j]-1)))
                    y-=(1<<(v[i][j]-1));
            }
            y = (y<<1) | (y>>1);
            if(y>=(1<<n))
                y-=(1<<n);
            G[k].pb(mp(y, i));
        }
    }
    int nod;
    Q[1] = mp(0, (1<<n)-1);
    dr=1;
    for(i=0;i<(1<<n)-1;i++)
        dist[i]=(1<<29);
    while(dr)
    {
        nod=Q[1].second;
        swap(Q[1], Q[dr]);
        dr--;
        r=1;
        while((r<<1) <= dr && Q[r]<max(Q[(r<<1)], Q[(r<<1)+1]) )
        {

            if((r<<1)==dr || max(Q[(r<<1)], Q[(r<<1)+1])==Q[(r<<1)])
            {
                swap(Q[r], Q[(r<<1)]);
                r=(r<<1);
            }
            else
            {
                swap(Q[r], Q[(r<<1)+1]);
                r=(r<<1)+1;
            }
        }
        for(iter it=G[nod].begin();it!=G[nod].end();it++)
        {

            if(dist[nod]+cost[it->second]<dist[it->first])
            {
                dist[it->first]=dist[nod]+cost[it->second];
                p[it->first]=mp(nod, it->second);
                Q[++dr]=mp(-dist[it->first], it->first);
                r=dr;
                while(r!=1 && Q[r]>Q[(r>>1)])
                {
                    swap(Q[r], Q[(r>>1)]);
                    r=(r>>1);
                }
            }
        }
    }
    cout << dist[0] << "\n";

    nod=0;

    while(nod!=(1<<n)-1)
    {
        X.push_back(p[nod].second);
        nod=p[nod].first;
    }
    cout << X.size() << "\n";
    for(i=X.size()-1;i>=0;i--)
    {
        cout << X[i] << "\n";
    }
    return 0;
}