Cod sursa(job #303225)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 9 aprilie 2009 17:38:13
Problema Gather Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
using namespace std;

#include <set>
#include <map>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <utility>
#include <algorithm>

#define pb push_back
#define sz size
#define f first
#define s second
#define II inline
#define ll long long
#define db double
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define all(v) v.begin() , v.end()
#define CC(v) memset((v),0,sizeof((v)))
#define CP(v,w) memcpy((v),(w),sizeof((w)))
#define mp make_pair

#define IN  "gather.in"
#define OUT "gather.out"
#define N_MAX 1<<10
#define bit(i) (1<<(i-1))
#define oo 1684300900

typedef vector<int> VI;
typedef pair<int,int> pi;
typedef pair<int,pi> str;

int K,N,M;
int Dist[N_MAX],d[16],D[16][(1<<15)+4],C[16][16][16],Nd[16];
vector< vector<str> > A(N_MAX);

II void scan()
{
	freopen(IN,"r",stdin);
	freopen(OUT,"w",stdout);
	scanf("%d%d%d",&K,&N,&M);
	
	FOR(i,1,K)
		scanf("%d",Nd+i);
	int x,y,p,c;
	FOR(i,1,M)
	{
		scanf("%d%d%d%d\n",&x,&y,&p,&c);
		A[x].pb( mp(y,mp(p,c)) );
		A[y].pb( mp(x,mp(p,c)) );
	}
}

struct comp{ bool operator() (int i,int j) {return Dist[i] > Dist[j];} };
priority_queue<int,VI,comp> Q;

II void Dijkastra(int k,int c)
{
	int G[N_MAX];
	CC(G);
	memset(Dist,100,sizeof(Dist));
	
	Q.push(Nd[k]);
	G[ Nd[k] ] = 1;
	Dist[ Nd[k] ] = 0;
	
	for(int nod;!Q.empty();)
	{
		--G[nod = Q.top() ];
		Q.pop();
		if(G[nod])
			continue;
		
		for(vector<str>::iterator it=A[nod].begin();it != A[nod].end();++it)
			if(Dist[it->f] > Dist[nod] + it->s.f && it->s.s >= c)
			{
				Dist[it->f] = Dist[nod] + it->s.f;
				Q.push(it->f);
				++G[it->f];
			}	
	}	
	
	FOR(i,0,K)
		C[k][i][c] = Dist[ Nd[i] ];
}

II void compute()
{
	memset(C,100,sizeof(C));
	
	FOR(i,1,K)
	FOR(c,1,K)
		Dijkastra(i,c);
	Nd[0] = 1;
	Dijkastra(0,0);	
}

II int getbit(int x)
{
	int bt(0);
	for(;x;bt += (x&1),x >>= 1);
	return bt;
}

II void solve()
{
	memset(D,100,sizeof(D));
	FOR(i,1,K)
		D[i][ bit(i) ] = C[0][i][0];
	
//	FOR(i,1,K)
//	FOR(j,1,K)
//		printf("pt %d %d : %d\n",Nd[i],Nd[j],C[i][j][2]);
	
	FOR(i,1,(1<<K)-1)
	FOR(k1,1,K)
	{
		int gbit = getbit(i);
		
		if(!(i & bit(k1) ))
			continue;
		FOR(k2,1,K)
		{
			if(!(i & bit(k2)) && C[k1][k2][gbit] != oo)
				D[k2][i | bit(k2)] = min(D[k2][i | bit(k2)],D[k1][i] + C[k1][k2][gbit] * (gbit+1) );
		}	
	}
	
	int rez(1<<30);
	FOR(i,1,K)
		rez = min(rez,D[i][ (1<<K)-1 ]);
	printf("%d\n",rez);	
}

int main()
{
	scan();
	compute();
	solve();
	return 0;
}