Cod sursa(job #929580)

Utilizator vandrei95Zamfir Vlad vandrei95 Data 27 martie 2013 09:33:40
Problema Ubuntzei Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.63 kb
#include<fstream>
#define N 2003
#define K 16
#define INFINIT 100000000
using namespace std;
int a[N][N],dist1[K][32770],dc[K][N];
void dijkstra(int x0,int d[],int n)
{
	int i,minim,vf;
	char viz[N]={0}; viz[x0]=1;
	for(i=1;i<=n;i++)
		d[i]=a[x0][i];
    do
	{
		minim=INFINIT;
		for(i=1;i<=n;i++)
			if(d[i]<minim && viz[i]==0)
			{
				minim=d[i]; vf=i;
			}
		if(minim<INFINIT)
		{
			viz[vf]=1;
			for(i=1;i<=n;i++)
				if(d[vf]+a[vf][i]<d[i] && viz[i]==0)
					d[i]=d[vf]+a[vf][i];
		}
    }
	while(minim!=INFINIT);
}
int main(void)
{
	int n,i,j,k,m,x,y,cost,c[K],d1[N],nrSub,s,distCrt,minim;
	fstream f("ubuntzei.in",ios::in),g("ubuntzei.out",ios::out);
	f>>n>>m>>k;
	for(i=0;i<k;i++)
		f>>c[i];
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			if(i!=j)
				a[i][j]=INFINIT;
	for(i=1;i<=m;i++)
	{
		f>>x>>y>>cost;	a[x][y]=a[y][x]=cost;
	}
	dijkstra(1,d1,n);
	if(k==0)
	{
		g<<d1[n]; g.close(); return 0;
	}
	for(i=0;i<k;i++)
		dijkstra(c[i],dc[i],n);
	nrSub=1<<k; //adica 2^k
	for(s=1;s<nrSub;s++)
	{
		for(i=0;i<k;i++)
			if(s==1<<i) //daca s are un singur element
			{
				dist1[i][s]=d1[c[i]]; break;
			}
		if(i<k) continue; //dist1[i][s] nu se poate optimiza
		for(i=0;i<k;i++)
		{
			dist1[i][s]=INFINIT;
			if(s & (1<<i)) //submultimea s contine bitul i
				for(j=0;j<k;j++)
					if(i!=j && (s & (1<<j)))
					{
						distCrt=dist1[j][s-(1<<i)] + dc[j][c[i]];
						if(distCrt<dist1[i][s])
							dist1[i][s]=distCrt;
					}
		}
	}
	minim=INFINIT;
	for(i=0;i<k;i++)
		if(dist1[i][nrSub-1] + dc[i][n] < minim)
			minim=dist1[i][nrSub-1] + dc[i][n];
	g<<minim;
	f.close(); g.close();
}