Cod sursa(job #621959)

Utilizator balakraz94abcd efgh balakraz94 Data 16 octombrie 2011 23:28:14
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.03 kb
#include<cstdio>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<cstring>
#define infile "ubuntzei.in"
#define outfile "ubuntzei.out"
#define n_max 2005
#define k_max 17
#define INF 0x3F3F3F3F
#define pb push_back
#define mkp make_pair
using namespace std;

vector < pair<int, int> > v[n_max], vk[1<<k_max];

vector <int> subset, id_subset(n_max);

bitset <n_max> in_subset;

int dist[k_max][1<<k_max];

int n, k, start, finish;



void citeste()
{
	freopen(infile,"r",stdin);
	
	int m, x, y, c;
	
	scanf("%d %d",&n,&m);
	
	scanf("%d",&k);
	
	for(int i=0;i<k;i++)
	{
		scanf("%d",&x);
		x--;
		
		subset.pb(x);
		id_subset[x] = i;
		in_subset[x] = 1;
	}
	
	subset.pb(start = 0);    id_subset[start] = subset.size()-1;  in_subset[start] = 1;
	subset.pb(finish = n-1); id_subset[finish] = subset.size()-1; in_subset[finish] = 1;
	
	while(m--)
	{
		scanf("%d %d %d",&x,&y,&c);
		x--, y--;
		
		v[x].pb(mkp(y,c));
		v[y].pb(mkp(x,c));
	}
	
	fclose(stdin);
}


vector <int> dijkstra(int start)
{
	priority_queue < pair <int, int> > h;
	
	vector <int> d(n, INF);
	
	vector< pair <int, int> > ::iterator it;
	
	d[start] = 0;
	h.push(mkp(0,start));
	
	while(!h.empty())
	{
		int x = h.top().second;
		h.pop();
		
		for(it=v[x].begin(); it!=v[x].end(); ++it)
		{
			int y = (*it).first;
			int cost = (*it).second;
			
			if(d[x] + cost < d[y])
			{
				d[y] = d[x] + cost;
				h.push(mkp(-d[y],y));
			}
		}
	}
	
	return d;
}




int dijkstraK(int start, int finish, int nk)
{
	priority_queue < pair <int, pair <int, int> > > h;
	
	vector< pair <int, int> > ::iterator it;
	
	memset(dist, INF, sizeof(dist));
	
	dist[start][1<<start] = 0;
	h.push(mkp(0, mkp(start, 1<<start)));
	
	while(!h.empty())
	{
		int x = h.top().second.first;
		int s = h.top().second.second;
		
		h.pop();
		
		for(it = vk[x].begin(); it!=vk[x].end(); ++it)
		{
			int y = (*it).first;
			int cost = (*it).second;
			
			if(!(s & (1<<y)))
			{
				int t = s | (1<<y);
				if(dist[x][s] + cost < dist[y][t] )
				{
					dist[y][t] = dist[x][s] + cost;
					h.push( mkp(-dist[y][t], mkp(y,t) ) );
				}
			}
		}
	}
	
	return dist[finish][ (1<<nk)-1 ];
}



void afiseaza(int sol)
{
	freopen(outfile,"w",stdout);
	
	printf("%d\n",sol);
	
	fclose(stdout);
}



void rezolva()
{
	vector <int> d;

	d = dijkstra(start);
	
	for (size_t i = 0; i < d.size(); ++i) 
		if (in_subset[i] && (int)i!=start) 
			vk[id_subset[start]].pb( mkp( id_subset[i], d[i] ) );

	if (k == 0) 
	{
		afiseaza(d[n-1]);
		return;
	}
	
	for (size_t i = 0; i < subset.size(); ++ i) 
		if (subset[i] != start && subset[i] != finish) 
		{
			d = dijkstra(subset[i]);
			
			for (size_t j = 0; j < d.size(); ++ j) 
				if (in_subset[j] && subset[i] != (int)j) 
					vk[i].pb( mkp(id_subset[j], d[j] ) );
		}

	int answer = dijkstraK( id_subset[start], id_subset[finish], subset.size() );
	
	afiseaza(answer);
}




int main()
{
	citeste();
	rezolva();
	
	return 0;
}