Cod sursa(job #2272857)

Utilizator shantih1Alex S Hill shantih1 Data 30 octombrie 2018 18:56:16
Problema Gather Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.87 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define ll long long
#define inf 1000000000000000000LL

using namespace std;
ifstream fin("gather.in");
ofstream fout("gather.out");

ll n,k,m,i,j,nr,x,a,b,y,msk,rez,l;
ll id[800],c[20],bt[66000],p[66000];
ll dr[18][18][18],rz[66000][18],dis[800];
struct drum
{	ll nd,cst,mx;	};
struct nod
{	ll nd,cst;
	bool operator<(const nod &alt)const
	{	return cst>alt.cst;	}
};
vector<drum> ad[800];
priority_queue<nod> q;

void dijkstra(ll a,ll nrx)
{
	ll i,nd,cst;
	for(i=0;i<=n;i++)
		dis[i]=inf;

	dis[a]=0;
	q.push({a,0});
	while(!q.empty())
	{
		nd=q.top().nd;
		cst=q.top().cst;
		q.pop();
		
		for(auto j:ad[nd])
		{
			if(j.mx<nrx)	continue;
			if(cst+(nrx+1)*j.cst<dis[j.nd])
			{
				dis[j.nd]=cst+(nrx+1)*j.cst;
				q.push({j.nd,dis[j.nd]});
			}
		}
	}
	dis[a]=inf;
	for(i=1;i<=n;i++)
		if(dis[i]!=inf&&dis[i]>=0)
			dr[id[a]][id[i]][nrx]=dis[i];
}

int main() {
 
	fin>>k>>n>>m;
	c[1]=1;
	id[1]=1;
	k++;
	for(i=2;i<=k;i++)
		fin>>c[i], id[c[i]]=i;
 
	for(;m--;)
	{
		fin>>i>>j>>a>>x;
		ad[i].push_back({j,a,x});
		ad[j].push_back({i,a,x});
	}
 
	for(i=0;i<=k+1;i++)
		for(j=0;j<=k+1;j++)
			for(l=0;l<=k+1;l++)
				dr[i][j][l]=inf;
 
	for(i=1;i<=k;i++)
		for(j=0;j<=k;j++)
			dijkstra(c[i],j);
 
	for(i=1;i<=66000;i*=2)
		p[i]=p[i/2]+1;
 
	for(i=2;i<=k;i++)
		rz[1|(1<<(i-1))][i]=dr[1][i][0], bt[1|(1<<(i-1))]=1;

	l=(1<<k)-1;
	for(msk=3;msk<=l;msk+=2)
	{
		if(((msk-1)&(msk-2))==0)	continue;
		x=msk-1;
		while(x)
		{
			i=p[(x^(x-1))&x];
			rz[msk][i]=inf;
			n=msk-(1<<(i-1));
			y=n-1;
			while(y)
			{
				j=p[(y^(y-1))&y];
				if(rz[n][j]+dr[j][i][bt[n]]<rz[msk][i]&&rz[n][j]!=inf&&rz[n][j]>=0&&dr[j][i][bt[n]]!=inf&&dr[j][i][bt[j]]>=0)
				rz[msk][i]=rz[n][j]+dr[j][i][bt[n]];
				y&=y-1;
			}
			bt[msk]++;
			x&=x-1;
		}
	}
	rez=inf;
	for(i=2;i<=k;i++)
		if(rz[l][i]!=inf&&rz[l][i]>=0)
			rez=rz[l][i];
 
	fout<<rez<<"\n";
}