Cod sursa(job #582292)

Utilizator Bogdan_tmmTirca Bogdan Bogdan_tmm Data 15 aprilie 2011 10:28:26
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.84 kb
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

#define N_MAX 2002
#define INF (1<<29)

int n,m,i,j,jj,x,y,z,k;

int v[20];
int dist[20][20];

int cost[N_MAX];
bool ut[N_MAX];

struct cmp
{
	bool operator () (const int &a,const int &b) const
	{
		return cost[a]>cost[b];
	}
};

struct nod_s
{
	int y,cost;
	
	nod_s()
	{
	}
	
	nod_s(const int y,const int cost)
	{
		this->y=y;
		this->cost=cost;
	}
};
vector <nod_s> a[N_MAX];
vector <nod_s> ::iterator it;

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

void dijkstra(int nod)
{
	int i,j;
	for(i=1;i<=n;i++)
	{
		cost[i]=INF;
		ut[i]=0;
	}
	
	cost[nod]=0;
	PQ.push(nod);	ut[nod]=1;
	
	while(!PQ.empty())
	{
		int nd=PQ.top();
		PQ.pop();	ut[nd]=0;
		
		for(it=a[nd].begin();it!=a[nd].end();it++)
		{
			if(cost[it->y]<=cost[nd]+it->cost)
				continue;
			
			cost[it->y]=cost[nd]+it->cost;
			
			if(!ut[it->y])
			{
				PQ.push(it->y);
				ut[it->y]=1;
			}
		}
	}
}

int dp[(1<<17)][17];

int main()
{
	freopen("ubuntzei.in","r",stdin);
	freopen("ubuntzei.out","w",stdout);
	
	scanf("%d%d",&n,&m);
	scanf("%d",&k);
	
	v[0]=1;
	for(i=1;i<=k;i++)
	{
		scanf("%d",&v[i]);
	}
	
	v[++k]=n;	++k;
	
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		
		a[x].push_back(nod_s(y,z));
		a[y].push_back(nod_s(x,z));
	}
	
	for(i=0;i<k;i++)
	{
		dijkstra(v[i]);
		
		for(j=0;j<k;j++)
			dist[i][j]=cost[v[j]];
	}
	
	for(i=0;i<(1<<k);i++)
		for(j=0;j<k;j++)
			dp[i][j]=INF;
		
	dp[1][0]=0;
	
	for(i=3;i<(1<<k);i++)
	{
		for(j=0;j<k;j++)
		{
			if( (i&(1<<j))==0 )
				continue;
			
			for(jj=0;jj<k;jj++)
			{
				if( ((i-(1<<j))&(1<<jj))==0)
					continue;
				
				dp[i][j]=min(dp[i][j],dp[i-(1<<j)][jj]+dist[jj][j]);
			}
		}
	}
	
	printf("%d\n",dp[(1<<k)-1][k-1]);
	
	return 0;
}