Cod sursa(job #694028)

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

using namespace std;

int q,j,nod,nod2,y,c,x,n,m,i,k,D[Nmax],Dmin[Kmax][Kmax],K[Kmax],sol[Kmax][1<<Kmax];
short int 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][K[i]]=D[1];
		Dmin[K[i]][n]=D[n];
		for (j=1;j<=k;j++)
			if (j!=i) Dmin[K[i]][K[j]]=D[K[j]];
	}
	for (i=1;i<=k+1;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][K[i]];
					sol[k+1][j]=sol[i][j]+Dmin[K[i]][n];
				}
				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[K[q]][K[i]]);
						sol[k+1][j]=min(sol[k+1][j],sol[i][j]+Dmin[K[i]][n]);
					}
			}
	}
	printf("%d\n",sol[k+1][(1<<k)-1]);
}