Cod sursa(job #1461137)

Utilizator heracleRadu Muntean heracle Data 14 iulie 2015 20:26:21
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.62 kb
#include <cstdio>
#include <queue>
#include <cstring>

FILE* in=fopen("team.in","r");
FILE* out=fopen("team.out","w");

const int Q=507,W=57,INF=2000000000;


int dist[Q][Q];

int d[W][W][W];





int p,n,m;

int dest[W];

int lst[Q],val[Q*Q],nxt[Q*Q],cost[Q*Q],nr;


struct tipe
{
	int dest,cost;
};

bool operator <(const tipe &una, const tipe &alta)
{
	return una.cost>alta.cost;
}

std::priority_queue<tipe> h;

bool viz[Q];

void disk(int x)
{
	if(dist[x][x]==0)
		return;

	memset(viz,0,sizeof viz);

	viz[x]=1;

	dist[x][x]=0;


	for(int i=1; i<n; i++)
	{
		int min=0,vmin=INF;

		for(int j=1; j<=n; j++)
		{
			if(viz[j]==0 && dist[x][j]<vmin)
			{
				vmin=dist[x][j];
				min=j;
			}
		}

		viz[min]=1;

		for(int j=1; j<=n; j++)
		{
			if(dist[x][min]+dist[min][j] < dist[x][j])
			{
				dist[x][j]=dist[x][min]+dist[min][j];
			}
		}
	}



/*
	if(dist[x][x]==0)
		return;

	dist[x][x]=0;

	while(!h.empty())
	{
		h.pop();
	}

	for(int i=1; i<=p; i++)
		h.push(tipe{i,dist[dest[i]][dest[x]]});

	tipe act;

	while(!h.empty())
	{
		act=h.top();
		h.pop();

		if(dist[x][act.dest]<act.cost)
			continue;

		dist[x][act.dest]=act.cost;

		for(int p=lst[act.dest];p ;p=nxt[p])
		{
			if(dist[x][val[p]]>act.cost+cost[p])
			{
				h.push(tipe{val[p],act.cost+cost[p]});
			}
		}
	}

	*/
}



void add(int a, int b, int c)
{
	nr++;
	val[nr]=b;
	cost[nr]=c;
	nxt[nr]=lst[a];
	lst[a]=nr;
}



int min(const int &a, const int &b)
{
	return a<b?a:b;
}

int main()
{
	fscanf(in,"%d%d%d",&p,&n,&m);

	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=n; j++)
		{
			dist[i][j]=INF;
		}
	}


	int a,b,c;

	for(int i=1; i<=m; i++)
	{
		fscanf(in,"%d%d%d",&a,&b,&c);

		add(a,b,c);
		add(b,a,c);

		dist[a][b]=c;
		dist[b][a]=c;
	}

	for(int i=1; i<=p; i++)
	{
		fscanf(in,"%d",&dest[i]);
	}

	p++;
	dest[p]=1;



	for(int i=1; i<=p; i++)
	{
		disk(dest[i]);
	}

	for(int i=1; i<=p; i++)
	{
		for(int j=i; j<=p; j++)
		{
			for(int t=1; t<=p; t++)
			{
				d[i][j][t]=INF;
			}
		}
	}


	for(int i=1; i<=p; i++)
	{
		//d[i][i][i]=0;
		for(int k=1; k<=p; k++)
			d[i][i][k]=dist[dest[i]][dest[k]] ;
	}

	for(int dif=1; dif<=p-1; dif++)
	{
		for( a=1; a<=p-dif; a++)
		{
			 b=a+dif;

			 for(int k=1; k<=p; k++)
			 {
				d[a][b][k]=INF;


				//d[a][b][k]=d[a+1][b][k]+dist[dest[a]][dest[k]];

				//d[a][b][k]=min(d[a][b][k],d[a][b-1][k]+dist[dest[b]][dest[k]]);

				for(int u=a; u<=b; u++)
				{
					int act=dist[dest[u]][dest[k]];
					act+=d[a][u-1][u];
					act+=d[u+1][b][u];

					if(act<d[a][b][k])
						d[a][b][k]=act;

					//d[a][b][k]=min(d[a][b][k], d[a][u-1][k]+d[u+1][b][k]+dist[dest[u]][dest[k]]);
				}
			 }
		}
	}

	fprintf(out,"%d\n",d[1][p][p]);

    return 0;
}