Pagini recente » Cod sursa (job #2719555) | Cod sursa (job #2289393) | Cod sursa (job #2413251) | Cod sursa (job #3222728) | Cod sursa (job #949257)
Cod sursa(job #949257)
#include <cstdio>
#include <queue>
#include <cstring>
#define In "ubuntzei.in"
#define Out "ubuntzei.out"
#define Nmax 2000
#define Kmax 15
#define Inf 0x3f3f3f3f
#define min(a,b) ((a)<=(b)?(a):(b))
#define PAIR pair< int , int >
#define nod first
#define cost second
#define mp make_pair
#define pb push_back
using namespace std ;
int N, K, MAX_STARE;
int a[Kmax];//retine multimea celor k orase
int Dist[Kmax][Nmax];
///Dist[i][j] = distanta minima de la a[i] la j
int dp[Kmax][1<<Kmax];
///dp[i][j] = costul minim pentru a ajunge din nodul 0 in al i-lea oras
///vizitand nodurile care faca parte din multimea bitilor de 1 a alui j
vector< PAIR >Graf[Nmax];//graful initial
inline void Citire()
{
int x,y,c,M,i;
freopen(In,"r",stdin);
freopen(Out,"w",stdout);
scanf("%d %d %d",&N,&M,&K);
for(i = 0;i < K; i++)
{
scanf("%d ",&a[i]);
a[i]--;
}
while(M--)
{
scanf("%d %d %d",&x,&y,&c);
x--,y--;
Graf[x].pb(mp(y,c));
Graf[y].pb(mp(x,c));
}
MAX_STARE = (1<<K)-1;//numarul cu exact K biti de 1
}
struct cmp
{
bool operator () (const PAIR &A,const PAIR &B)
{
return A.cost > B.cost;
}
};
inline void Dijkstra(int i,int nod)
{
priority_queue< PAIR,vector< PAIR >,cmp >Q;
Dist[i][nod] = 0;
Q.push(mp(nod,0));
PAIR act;
while(!Q.empty())
{
act = Q.top();
Q.pop();
for(vector< PAIR >::iterator vec=Graf[act.nod].begin();vec!=Graf[act.nod].end();vec++)
if(Dist[i][(*vec).nod] > Dist[i][act.nod]+(*vec).cost)
{
Dist[i][(*vec).nod] = Dist[i][act.nod]+(*vec).cost;
Q.push(mp((*vec).nod, Dist[i][(*vec).nod]));
}
}
}
inline void Afisare()
{
int i,sol = Inf;
for(i = 0;i < K ;i++)
sol = min(sol,dp[i][MAX_STARE] + Dist[i][N-1]);
printf("%d\n",sol);
}
inline void Init()
{
int i;
memset(Dist,Inf,sizeof(Dist));
memset(dp,Inf,sizeof (dp));
for(i = 0;i < K ;i++)
Dijkstra(i,a[i]);
for(i = 0;i < K ;i++)
dp[i][1<<i] = Dist[i][0];//distanta de la 0 la a[i] folosind multimea 2^i este dist[i][0]
}
int main()
{
Citire();
Init();
int i,j,stare;
if(K==0)
{
Dijkstra(0,0);
printf("%d\n",Dist[0][N-1]);
return 0;
}
for(stare = 1;stare <= MAX_STARE ;stare++)//pentru fiecare stare
for(i = 0;i < K ;i++)
if((stare & (1<<i))!=0)//procesam fiecare bit
for(j = 0;j < K ;j++)//incercam sa venim din j
if(i!=j &&(stare & (1<<j))!=0)//acesta trebuie sa apartina multimii
dp[i][stare] = min(dp[i][stare],dp[j][stare-(1<<i)] + Dist[j][a[i]]);
Afisare();
return 0;
}