Cod sursa(job #2271505)

Utilizator shantih1Alex S Hill shantih1 Data 28 octombrie 2018 18:29:37
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.7 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#define inf 2147483647
#define fi first
#define se second

using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

int n,m,k,i,j,nr,x,y;
int c[20],dr[20][20],id[2005],dis[2005];
int rz[135000][20],p[25],bt[25];
vector<pair<int, int>> ad[2005];
set<pair<int, int>> qset;
struct nod
{	int m,nd,c;	
	bool operator<(const nod &alt)const
	{	return c>alt.c;	}
};

void dijkstra(int nd)
{
	int i,x,y;
	for(i=1;i<=n;i++)
		dis[i]=0;
 
	qset.insert({0, nd});
	dis[nd]=0;
	while(!qset.empty())
	{
		y=qset.begin()->fi;
		x=qset.begin()->se;
		qset.erase(qset.begin());
		if(y<dis[x])	continue;
		
		dr[id[nd]][id[x]]=min(dr[id[nd]][id[x]], y);
		for(auto i: ad[x])
			if(dis[i.fi]==0 || y+i.se<dis[i.fi])
			{
				dis[i.fi]=y+i.se;
				qset.insert({y+i.se, i.fi});
			}
	}
}
int main () {
	
	fin>>n>>m;
	fin>>k;
	c[++nr]=1;
	for(i=1;i<=k;i++)
		fin>>c[++nr];
	c[++nr]=n;
	k=nr;
	for(i=1;i<=k;i++)
		id[c[i]]=i;
	
	while(m--)
	{
		fin>>i>>j>>nr;
		ad[i].push_back({j,nr});
		ad[j].push_back({i,nr});
	}
	
	for(i=1;i<=k;i++)
		for(j=1;j<=k;j++)
			dr[i][j]=inf;
	
	for(i=1;i<=k;i++)
		dijkstra(c[i]);
	
	for(i=1;i<=k;i++)
		for(j=1;j<=k;j++)
			rz[(1<<(i-1))|(1<<(j-1))][j]=dr[i][j];
	
	for(i=1;i<=140000;i*=2)
		rz[i][0]=rz[i/2][0]+1;
	
	int l=(1<<k)-1,msk,m;
	rz[1][1]=0;
	for(msk=3;msk<=l;msk+=2)
	{
		m=msk;
		nr=0;
		while(m)
		{
			bt[++nr]=rz[((m-1)^m)&m][0];
			m&=m-1;
		}
		if(nr<=2)	continue;
		m=msk;
		for(i=2;i<=nr;i++)
		{
			rz[m][bt[i]]=inf;
			n=m-(1<<(bt[i]-1));
			x=n;
			while(x)
			{
				j=(x^(x-1))&x;
				y=rz[j][0];
				rz[m][bt[i]]=min(rz[m][bt[i]],rz[n][y]+dr[y][bt[i]]);
				x&=x-1;
			}
		}
	}
	fout<<rz[l][bt[k]]<<"\n";
}