Pagini recente » Borderou de evaluare (job #361433) | Borderou de evaluare (job #1882486) | Borderou de evaluare (job #373217) | Borderou de evaluare (job #2240561) | Cod sursa (job #1263021)
#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;
}