Pagini recente » Cod sursa (job #876951) | Cod sursa (job #340539) | Cod sursa (job #1397487) | Cod sursa (job #2067915) | Cod sursa (job #584441)
Cod sursa(job #584441)
#include <fstream>
#include <vector>
using namespace std;
const int NMAX = 2002;
const int KMAX = 15;
const int Inf = 0x3f3f3f3f;
const long long INF = 6666666666666666LL;
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
int N, M, K;
vector< pair<int, int> > G[NMAX];
vector<int> C;
void read()
{
ifstream fin("ubuntzei.in");
fin>>N>>M>>K;
C.resize(K+2);
for (int i=1;i<=K;++i) fin>>C[i];
while (M--)
{
int i, j, k;
fin>>i>>j>>k;
G[i].pb(mp(j, k));
G[j].pb(mp(i, k));
}
fin.close();
}
int h[NMAX],d[NMAX],p[NMAX];
void heap_up(int k)
{
while (k>1 && d[h[k>>1]]>d[h[k]])
{
swap(h[k>>1], h[k]);
p[h[k]]=k;
k>>=1;
}
p[h[k]]=k;
}
void heap_down(int k)
{
while (1)
{
int son=k<<1;
if (son > h[0]) break;
if (son+1 <= h[0] && d[h[son+1]]<d[h[son]]) ++son;
if (d[h[k]] <= d[h[son]]) break;
swap(h[k], h[son]);
p[h[k]]=k;
k=son;
}
p[h[k]]=k;
}
void heap_build()
{
for (int i=h[0]>>1;i;--i) heap_down(i);
}
int heap_extractmin()
{
int ret=h[1];
swap(h[1], h[h[0]--]);
p[h[1]]=1;
heap_down(1);
return ret;
}
void dijkstra(int source)
{
for (int i=1;i<=N;++i) d[i]=Inf;
d[source]=0;
h[0]=N;
for (int i=1;i<=N;++i) h[i]=i, p[i]=i;
heap_build();
for (int i=1;i<=N;++i)
{
int x=heap_extractmin();
for (vector< pair<int, int> >::iterator it=G[x].begin();it!=G[x].end();++it)
if (d[it->ff] > d[x]+it->ss)
{
d[it->ff]=d[x]+it->ss;
heap_up(p[it->ff]);
}
}
}
int a[KMAX+2][KMAX+2];
void build_a()
{
dijkstra(3);
C[0]=1;C[K+1]=N;
for (int i=0;i<K+2;++i)
{
dijkstra(C[i]);
for (int j=0;j<K+2;++j)
a[i][j]=d[C[j]];
}
for (int i=0;i<K+2;++i)
{
for (int j=0;j<K+2;++j) printf("%d ",a[i][j]);
printf("\n");
}
}
long long din[1<<KMAX][KMAX+1];
void solve() //find min-cost hamiltonian path
{
for (int j=0;j<(1<<K);++j)
for (int i=0;i<K+1;++i)
din[j][i]=INF;
din[0][0]=0;
for (int i=1;i<(1<<K);++i)
{
for (int j=1;j<K+1;++j)
{
int r=i^(1<<(j-1));
if (r == 0) { din[i][j] = a[0][j]; continue; }
if (!((1<<(j-1))&i)) continue;
for (int k=1;k<K+1;++k)
if (k!=j && ((1<<(k-1))&i))
din[i][j] = min(din[i][j], din[r][k]+a[k][j]);
}
}
long long ans=INF;
for (int i=0;i<=K;++i)
ans=min(ans, din[(1<<K)-1][i] + a[i][K+1]);
ofstream fout("ubuntzei.out");
fout<<ans<<"\n";
fout.close();
}
int main()
{
read();
build_a();
solve();
return 0;
}