Cod sursa(job #700521)

Utilizator valentina506Moraru Valentina valentina506 Data 1 martie 2012 10:47:34
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.06 kb
// Filip Buruiana
#include <stdio.h>
#include <vector>
#include <set>
using namespace std;

#define minim(a, b) ((a < b) ? a : b)
#define INF 999999999
#define KMAX 15
#define NMAX 10005
#define pii pair<int, int>
#define f first
#define s second
#define mp make_pair
#define pb push_back

int N, M, K, C[KMAX];
int source[NMAX], path[KMAX][NMAX];
vector<pii> G[NMAX];
int pd[1<<KMAX][KMAX];
set<pii> q;
unsigned int n,m,i,j,k,a[2001][2001],v[2001],x,y,c,s,minim,minct;
bool uz[2001];
int sol[2001];

inline int bit(int x, int nr)
{ return (x & (1<<nr)) != 0; }

void dijkstra(int sursa, int *sol)
{
	int i, vec;
	for (i = 1; i <= N; ++i)
		sol[i] = INF;
	sol[sursa] = 0;
	q.clear();
	for (i = 1; i <= N; ++i)
		q.insert(mp(sol[i],i));
	for (i = 1; i < N; ++i)
	{
		pii top = *q.begin();
		q.erase(q.begin());
		int nod = top.s;
		if (sol[nod] < top.f)  continue;
		for (size_t j = 0; j < G[nod].size(); ++j)
			if (sol[vec = G[nod][j].f] > sol[nod] + G[nod][j].s)
			{
				sol[vec] = sol[nod] + G[nod][j].s;
				q.insert(mp(sol[vec], vec));
			}
	}
}
inline void det(int k,int minct)
{
	int i;
	
	if(k==s+2)
	{
		minct+=a[sol[k-1]][n];
		if(minct<minim)
			minim=minct;
	}
	else
	for(i=1;i<=s;++i)
		if(!uz[v[i]])
		{
			uz[v[i]]=1;
			sol[k]=v[i];
			minct+=a[sol[k-1]][sol[k]];
			det(k+1,minct);
			uz[v[i]]=0;
			minct-=a[sol[k-1]][sol[k]];
		}
}



void calc()
{

        n=N;
		m=M;
		s=K;
		for(i=1;i<=s;++i)
			scanf("%d",&v[i]);
		//f>>v[i];
	
	for(i=1;i<=m;++i)
	{
		scanf("%d%d%d",&x,&y,&c);
	//	f>>x>>y>>c;
		a[x][y]=a[y][x]=c;
	}
	
	 for(k = 1;k <= n;k++)
        for(i = 1;i <= n;i++)
            for(j = 1;j <= n;j++)
                if(a[i][k] && a[k][j] && (a[i][k] + a[k][j] < a[i][j] || !a[i][j]) && i != j)
                    a[i][j] = a[i][k] + a[k][j];
				
				if(s)
				{
				    minim=1<<30;
				    minct=0;
				    sol[1]=1;
				    det(2,0);
					printf("%d",minim);
				}
				else
					printf("%d",a[1][n]);
}






int main()
{
	int i, j, k, newCost;

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

	scanf("%d %d %d", &N, &M, &K);
	
	
	if(K>9)
	{
	for (i = 0; i < K; ++i)
		scanf("%d", &C[i]);

	for (; M; --M)
	{
		scanf("%d %d %d", &i, &j, &k);
		G[i].pb(mp(j,k));
		G[j].pb(mp(i,k));
	}

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

	for (i = 0; i < K; ++i)
		dijkstra(C[i], path[i]);

	for (i = 1; i < (1<<K); ++i)
	{
		for (j = 0; j < K; ++j)
			if (i == (1<<j))
				break;
		if (j < K && i == (1<<j))
		{
			pd[i][j] = source[C[j]];
			continue;
		}
		
		for (j = 0; j < K; ++j)
		{
			pd[i][j] = INF;
			if (bit(i,j))
				for (k = 0; k < K; ++k)
					if (k != j && bit(i, k))
					{
						newCost = pd[i-(1<<j)][k] + path[k][C[j]];
						pd[i][j] = minim(pd[i][j], newCost);
					}
		}
	}

	int bst = INF;
	for (i = 0; i < K; ++i)
		bst = minim(bst, pd[(1<<K)-1][i] + path[i][N]);

	printf("%d\n", bst);
	}
	else
		
	calc();

	return 0;
}