Cod sursa(job #694207)

Utilizator Eugen01Vasilescu Eugen Eugen01 Data 27 februarie 2012 19:18:59
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.77 kb
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
#define Nmax 2009
#define Kmax 17
#define pb push_back
#define inf 0x3f3f3f3f

using namespace std;

int MIN=inf,q,j,nod,nod2,y,c,x,n,m,i,k,D[Nmax],Dmin[Kmax][Kmax],K[Kmax],sol[Kmax][1<<Kmax],cost[Nmax][Nmax];
vector<int> a[Nmax];
vector<int>::iterator it;

struct cmp
{
	bool operator() (const int &x,const int &y)
	{
		return D[x]>D[y];
	}
};

priority_queue<int,vector<int>,cmp> Q;

void dijkstra(int start)
{
	memset(D,inf,sizeof(D));
	D[start]=0;
	Q.push(start);

	while (!Q.empty())
	{
		nod=Q.top();
		for (it=a[nod].begin();it!=a[nod].end();it++)
		{
			nod2=*it;
			if (D[nod]+cost[nod][nod2]<D[nod2])
			{
				D[nod2]=D[nod]+cost[nod][nod2];
				Q.push(nod2);
			}
		}
		Q.pop();
	}
}

inline int min(int a,int b)
{
	if (a<b) return a;
	return b;
}

int main()
{
	freopen("ubuntzei.in","r",stdin);
	freopen("ubuntzei.out","w",stdout);

	scanf("%d%d%d",&n,&m,&k);
	for (i=1;i<=k;i++) scanf("%d",&K[i]);

	for (i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&c);
		a[x].pb(y);
		a[y].pb(x);
		cost[x][y]=c;
		cost[y][x]=c;
	}

	if (k==0)
	{
		dijkstra(1);
		printf("%d\n",D[n]);
		return 0;
	}

	for (i=1;i<=k;i++)
	{
		dijkstra(K[i]);
		Dmin[0][i]=D[1];
		Dmin[i][k+1]=D[n];
		for (j=1;j<=k;j++)
			if (j!=i) Dmin[i][j]=D[K[j]];
	}
	for (i=1;i<=k;i++)
		memset(sol[i],inf,sizeof(sol[i]));
	for (j=1;j<(1<<k);j++)
	{
		for (i=1;i<=k;i++)
			if (j & (1<<(i-1)))
			{
				if ((j & (j-1))==0)
					sol[i][j]=Dmin[0][i];
				for (q=1;q<=k;q++)
					if ((j & (1<<(q-1))) && q!=i)
						sol[i][j]=min(sol[i][j],sol[q][j^(1<<(i-1))]+Dmin[q][i]);
			}
	}
	for (i=1;i<=k;i++)
		MIN=min(MIN,sol[i][(1<<k)-1]+Dmin[i][k+1]);

	printf("%d\n",MIN);
}