Pagini recente » Cod sursa (job #2690029) | Cod sursa (job #212867) | Cod sursa (job #1621433) | Cod sursa (job #2406506) | Cod sursa (job #3193459)
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#define N 2005
#define pinf 2e+8
using namespace std;
int D2[20][131100];
long long D[N];
struct Nod
{
int nod,s;
long long cost;
};
class Compar //vezi priority_queue.pdf
{
public:
bool operator()( Nod &x, Nod &y)
{
if(x.cost>y.cost) return true; // ordine crscatoare
else return false;
}
};
priority_queue< Nod, vector< Nod >, Compar > coada;
int n,m,nrs,vk[20],k;
vector < vector<pair<int,int> > >L(N);
vector < vector < Nod > >L2(20);
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
int sel[2005][2];
void dijkstra2(int r)
{
int i,poz,c,j,sub,w;
for(i=1;i<=k+2;i++)
for(j=0;j<=nrs;j++)
D2[i][j]=pinf;
Nod x,y;
x.cost=0;x.nod=r;x.s=0;
if(sel[r][0]) //face parte din mult
{
x.s=(x.s|(1<<sel[r][1]));
D2[sel[r][1]][x.s]=0;
}
else D2[sel[r][1]][0]=0;
coada.push(x);
while(!coada.empty())
{
x=coada.top(); //cout<<x.nod<<endl;
coada.pop();
if(x.nod==n and x.s==nrs) break;
// cout<<x.nod<<" "<<x.s<<endl;
if(D2[sel[x.nod][1]][x.s]==x.cost) //daca poz e la distanta minima fata de sursa
{
w=sel[x.nod][1];
for(i=0;i<L2[w].size();i++)
{
// sub=(sub|(1<<sel[L2[sel[x.nod][1]][i].first][1]));
sub=(x.s|L2[w][i].s);
if(D2[sel[L2[w][i].nod][1]][sub]>D2[w][x.s]+L2[w][i].cost ) //daca putem imbunatati distanta
{
D2[sel[L2[w][i].nod][1]][sub]=D2[w][x.s]+L2[w][i].cost;
y.nod=L2[w][i].nod;
y.cost=D2[sel[L2[w][i].nod][1]][sub];
y.s=sub;
coada.push(y);
//adaugam nodul si distanta imbunatatita in coada
}
}
}
}
}
void dijkstra1(int r)
{
int i,poz,c,j,sub;
for(i=1;i<=n;i++)
D[i]=pinf;
Nod x,y;
x.cost=0;x.nod=r;x.s=0;
if(sel[r][0]) //face parte din mult
{
x.s=(x.s|(1<<sel[r][1]));
}
D[r]=0;
coada.push(x);
while(!coada.empty())
{
x=coada.top();
coada.pop();
if(D[x.nod]==x.cost) //daca poz e la distanta minima fata de sursa
{
if(x.nod!=r)
if(sel[x.nod][0]) L2[sel[r][1]].push_back(x);
//parcurgem lista de adiacenta a lui poz
for(i=0;i<L[x.nod].size();i++)
{
sub=x.s;
if(sel[L[x.nod][i].first][0]) //face parte din mult
{
sub=(sub|(1<<sel[L[x.nod][i].first][1]));
}
if(D[L[x.nod][i].first]>D[x.nod]+L[x.nod][i].second ) //daca putem imbunatati distanta
{
D[L[x.nod][i].first]=D[x.nod]+L[x.nod][i].second;
y.nod=L[x.nod][i].first;
y.cost=D[L[x.nod][i].first];
y.s=sub;
coada.push(y);
//adaugam nodul si distanta imbunatatita in coada
}
}
}
}
}
int main()
{
int x,y,c,i;
f>>n>>m>>k;
for(i=1;i<=k;i++)
{
f>>c;vk[i]=c;
sel[c][0]=1;
sel[c][1]=i;
nrs=(nrs|(1<<i));
}
vk[0]=1;sel[1][0]=1; sel[1][1]=0; nrs=(nrs|(1<<0));
vk[k+1]=n;sel[n][0]=1; sel[n][1]=k+1; nrs=(nrs|(1<<k+1));
// cout<<nrs;
for(i=1;i<=m;i++)
{
f>>x>>y>>c; //cout<<7<<endl;
L[x].push_back(make_pair(y,c));
L[y].push_back(make_pair(x,c));
}
;
dijkstra1(1);
for(i=1;i<=k+1;i++) dijkstra1(vk[i]);
dijkstra2(1);
g<<D2[sel[n][1]][nrs]<<" ";
f.close();
g.close();
return 0;
}