Pagini recente » Cod sursa (job #2634762) | Cod sursa (job #848116) | Cod sursa (job #2093003) | Cod sursa (job #1274376) | Cod sursa (job #2148562)
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
#define inf 210005
#define nmax 2005
int n,m,k,u[nmax],dist[nmax][nmax],total,v[nmax],dp[1<<17][nmax],bitmx;
bool viz[nmax][nmax];
struct str
{
int vecin,cost;
bool operator <(const str &other)const
{
return cost<other.cost;
}
};
vector<str>Q[nmax];
priority_queue<str>que;
void read()
{
f>>n>>m>>k;
for (int i=1; i<=k; ++i)
f>>u[i];
for (int i=1; i<=m; ++i)
{
int e1,e2,e3;
f>>e1>>e2>>e3;
Q[e1].push_back({e2,e3});
Q[e2].push_back({e1,e3});
}
memset(dist,inf,sizeof(dist));
}
void Dijkstra(int nod)
{
dist[nod][u[nod]]=0;
que.push({u[nod],0});
while (!que.empty())
{
int cnod=que.top().vecin;
int ccost=que.top().cost;
que.pop();
if (dist[nod][cnod]>ccost)
continue;
for (auto w:Q[cnod])
{
if (ccost+w.cost<dist[nod][w.vecin])
{
dist[nod][w.vecin]=ccost+w.cost;
que.push({w.vecin,dist[nod][w.vecin]});
}
}
}
}
void solve2()
{
bitmx=(1<<k)-1;
memset(dp,inf,sizeof(dp));
for (int i=0; (1<<i)<bitmx; ++i)
dp[1<<i][i+1]=dist[i+1][1];
// cost[i][j] <=> costul drumului care porneste din localitatea u[i] pana la localitatea j
// dp[i][j] <=> costul pentru a intra in configuratia i cu ultima localitate j
// ca sa ajungi in configuratia unde bitul x == true (<=> am folosit localitatea u[x]),
// vom lua toate configuratiile asemanatoare, doar cu un bit fals in loc de true
// (adica am folosit cu o localitate mai putin) si vom updata costul
for (int i=1; i<=bitmx; ++i)
for (int j=0; j<k; ++j)
if (i&(1<<j))
{
int mask=i-(1<<j); //practic daca bitul j+1 e adevarat, il facem fals
for (int q=0; q<k; ++q)
{
if (mask&(1<<q))
{
dp[i][j+1]=min(dp[i][j+1],dp[mask][q+1]+dist[j+1][u[q+1]]);
}
// practic aici am luat mastile care au avut bitul q+1 true,
// astfel dp[mask][q+1] reprezinta configuratia mask care s a terminat
// in localitatea u[q+1]. evident, daca masca are bitul q+1 negativ,
// nu are cum sa se termine in localitatea u[q+1]
// astfel costul pentru a ajunge in configuratia i cu ultima localitate (j+1)
// este costul pentru a ajunge in configuratia mask cu ultima localitate (q+1) +
// + costul drumului care porneste in localitatea j+1, pana la localitatea (q+1)
}
}
}
void solve()
{
if (k==0)
{
u[1]=1;
Dijkstra(1);
g<<dist[1][n];
return;
}
else if (k==1)
{
Dijkstra(1);
g<<dist[1][n]+dist[1][1];
return;
}
for (int i=1; i<=k; ++i)
Dijkstra(i);
total=inf;
solve2();
for (int i=0; i<k; ++i)
total=min(total,dp[bitmx][i+1]+dist[i+1][n]);
g<<total;
}
int main()
{
read();
solve();
return 0;
}