Cod sursa(job #799219)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 18 octombrie 2012 13:13:31
Problema Gather Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.84 kb
#include<fstream>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
int n,m,K,cel[20];
struct Muchie{int x,y,lg,maxim;};
Muchie M[1300];
vector <int> G[760];
struct Configuratie{int conf,x;};
queue <Configuratie> Q;
int best[33000][760],nr[33000],sol=2000000000;
int detinut[760];

inline void Citire()
{
	int i;
	ifstream fin("gather.in");
	fin>>K>>n>>m;
	for(i=0;i<K;i++)
	{
		fin>>cel[i];
		detinut[cel[i]]=i+1;
	}
	for(i=1;i<=m;i++)
	{
		fin>>M[i].x>>M[i].y>>M[i].lg>>M[i].maxim;
		G[M[i].x].push_back(i);
		G[M[i].y].push_back(i);
	}
	fin.close();
}

inline void NumarBiti()
{
	int i,x;
	for(i=1;i<(1<<K);i++)
	{
		x=i;
		while(x)
		{
			if(x%2==1)
				nr[i]++;
			x/=2;
		}
	}
}

inline void BellmanFord()
{
	int i,conf,nod,lg,D;
	Configuratie aux,poz;
	vector <int>::iterator it;
	for(i=1;i<=n;i++)
		for(conf=0;conf<(1<<K);conf++)
			best[i][conf]=2000000000;
	aux.conf=0;
	aux.x=1;
	if(detinut[1])
		aux.conf=(1<<(detinut[1]-1));
	best[1][aux.conf]=0;
	Q.push(aux);
	while(!Q.empty())
	{
		aux=Q.front();
		Q.pop();
		if(aux.conf==(1<<K)-1)
		{
			sol=min(sol,best[aux.x][aux.conf]);
			continue;
		}
		if(best[aux.x][aux.conf]>=sol)
			continue;
		for(it=G[aux.x].begin();it!=G[aux.x].end();it++)
		{
			nod=M[*it].x+M[*it].y-aux.x;
			lg=M[*it].lg*(nr[aux.conf]+1);
			D=M[*it].maxim;
			conf=aux.conf;
			if(detinut[nod] && (conf&(1<<(detinut[nod]-1)))==0)
				conf+=(1<<(detinut[nod]-1));
			if(nr[aux.conf]<=D && best[nod][conf]>best[aux.x][aux.conf]+lg)
			{
				best[nod][conf]=best[aux.x][aux.conf]+lg;
				poz.x=nod;
				poz.conf=conf;
				Q.push(poz);
			}
		}
	}
}

inline void Afisare()
{
	ofstream fout("gather.out");
	fout<<sol<<"\n";
	fout.close();
}

int main()
{
	Citire();
	NumarBiti();
	BellmanFord();
	Afisare();
	return 0;
}