Cod sursa(job #2287546)

Utilizator xRoALexBirtoiu Alexandru xRoALex Data 22 noiembrie 2018 00:19:57
Problema Ciclu hamiltonian de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.78 kb
#include<queue>
#include <cstdio>
#define INF 1e9
#define Nmax (1<<20)+5
using namespace std;

FILE * f= fopen("boom.in","r");
FILE * g= fopen("boom.out","w");

int n,m;
int dp[Nmax];
int cst[55];
int v[55],nr[Nmax],pred[Nmax],last[Nmax];

struct tip
{
    int nod;
    int cost;
    bool operator<(const tip&x) const
    {
        return cost>x.cost;
    }
};

priority_queue<tip> q;

int main()
{
    fscanf(f,"%d%d",&n,&m);

    for(int masca=0; masca<(1<<n); masca++)
        dp[masca]=INF;

    dp[(1<<n)-1]=0;

    for(int i=1;i<=m;i++)
    {
        int x;
        fscanf(f,"%d",&cst[i]);
        fscanf(f,"%d",&x);
        int masca = (1<<n)-1;
        for(int j=1;j<=x;j++)
        {
            int y;
            fscanf(f,"%d",&y);
            masca=masca & ~ (1<<(y-1));
        }
        v[i]=masca;
    }

    q.push({(1<<n)-1,0});

    while(!q.empty())
    {
        int nod=q.top().nod;
        int cost=q.top().cost;
        q.pop();
        if(cost>dp[nod])
            continue;
        for(int i=1;i<=m;i++)
        {
            int mask=(nod&v[i]);
            mask=(mask>>1)|(mask<<1);
            if(mask>=(1<<n))
                mask-=(1<<n);
            if(dp[nod]+cst[i]<dp[mask])
            {
                nr[mask]=nr[nod]+1;
                last[mask]=i;
                pred[mask]=nod;
                dp[mask]=dp[nod]+cst[i];
                q.push({mask,dp[mask]});
            }
        }
    }
    fprintf(g,"%d\n",dp[0]);
    fprintf(g,"%d\n",nr[0]);

    int x=0;
    vector<int> ans;
    while(x != ((1<<n)-1))
    {
        ans.push_back(last[x]);
        x=pred[x];
    }

    while(!ans.empty())
    {
        fprintf(g,"%d\n",ans.back());
        ans.pop_back();
    }
    return 0;
}