Pagini recente » Cod sursa (job #473362) | Cod sursa (job #581615) | Cod sursa (job #1747353) | Cod sursa (job #2868731) | Cod sursa (job #675050)
Cod sursa(job #675050)
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>
#include <cstdlib>
#define INF 999999999
#define MAX_CITIES 17
#define MAXN 2001
using namespace std;
typedef unsigned short uint16;
typedef vector<vector<pair<uint16,int> > > Graph;
int cities[MAX_CITIES];
int distances[MAX_CITIES][MAXN];
int sourceDist[MAXN];
int cityDist[1<<MAX_CITIES][MAX_CITIES];
class CHeap
{
private:
uint16 size;
vector<uint16> vIndexes;
vector<pair<int,uint16> > vHeap;
inline void swap(const uint16 first, const uint16 second)
{
vIndexes[vHeap[first].second]=second;
vIndexes[vHeap[second].second]=first;
pair<int,uint16> aux;
aux=vHeap[first];
vHeap[first]=vHeap[second];
vHeap[second]=aux;
}
void siftUp(int index)
{
int parent=(index-1-!(index%2))>>1;
while(parent>=0 && vHeap[index].first<vHeap[parent].first)
{
swap(parent,index);
index=parent;
parent=(index-1-!(index%2))>>1;
}
}
void siftDown(int index)
{
int child1,child2;
bool ord=true;
child1=(index<<1)+1;
child2=(index+1)<<1;
while(ord && child1<size)
{
ord=false;
if(child2<size)
{
if(vHeap[child1].first<vHeap[child2].first)
{
if(vHeap[child1]<vHeap[index])
{
swap(child1,index);
index=child1;
ord=true;
}
}
else if(vHeap[child2].first<vHeap[index].first)
{
swap(child2,index);
index=child2;
ord=true;
}
}
else if(vHeap[child1].first<vHeap[index].first)
{
swap(child1,index);
index=child1;
ord=true;
}
child1=(index<<1)+1;
child2=(index+1)<<1;
}
}
public:
CHeap() : size(0)
{}
void insert(const pair<int,uint16>& val)
{
vHeap.push_back(val);
vIndexes.push_back(size++);
siftUp(size-1);
}
inline void modify(const int pos, const pair<int,uint16>& val)
{
vHeap[pos]=val;
siftUp(pos);
}
inline void remove(const int pos)
{
swap(pos,--size);
vHeap.pop_back();
siftDown(pos);
}
inline const pair<int,uint16>& getElement(const int pos) const
{
return vHeap[pos];
}
inline int getPos(const int index) const
{
return vIndexes[index];
}
inline bool empty() const
{
return (size==0);
}
void print()
{
for(unsigned int i=0; i<vHeap.size(); ++i)
{
cout<<"("<<vHeap[i].first<<" "<<vHeap[i].second<<") ";
}
cout<<endl;
}
};
void Dijkstra(Graph& graph, const int n, const uint16 src, int* dist)
{
CHeap heap;
//memset(dist,0x3f,n*sizeof(int));
for (int i=0; i<n; ++i)
{
heap.insert(make_pair(INF,i));
dist[i] = INF;
}
heap.modify(heap.getPos(src), make_pair(0,src));
dist[src] = 0;
while (!heap.empty())
{
const pair<int,uint16> node=heap.getElement(0);
dist[node.second] = node.first;
heap.remove(0);
if (node.first == INF)
break;
for (vector<pair<uint16,int> >::iterator it=graph[node.second].begin(); it!=graph[node.second].end(); ++it)
{
const int alt = dist[node.second]+it->second;
if (alt < dist[it->first])
{
dist[it->first] = alt;
heap.modify(heap.getPos(it->first),make_pair(alt,it->first));
}
}
}
}
int main()
{
int n, m, k;
Graph graph;
fstream fin("ubuntzei.in", fstream::in);
fstream fout("ubuntzei.out", fstream::out);
fin >> n >> m >> k;
//cout << n << " " << m << " " << k << endl;
graph.resize(n+1);
for (int i=0; i<k; ++i)
{
int x;
fin >> x;
cities[i] = x-1;
//cout << cities[i] << " ";
}
//cout << "\n";
for (int i=0; i<m; ++i)
{
int x,y,z;
fin >> x >> y >> z;
//cout << x << " " << y << " " << z << "\n";
graph[x-1].push_back(make_pair(y-1,z));
graph[y-1].push_back(make_pair(x-1,z));
}
Dijkstra(graph, n, 0, sourceDist);
if (0 == k)
{
fout << sourceDist[n-1] << "\n";
return 0;
}
for (int i=0; i<k; ++i)
{
Dijkstra(graph, n, cities[i], distances[i]);
}
for (int i=0; i<k; ++i)
{
cityDist[1<<i][i] = sourceDist[cities[i]];
}
for (int i=1; i<(1<<k); ++i)
{
if ((i & (i-1)) == 0)
{
continue;
}
for (int j=0; j<k; ++j)
{
cityDist[i][j] = INF;
if (i & (1<<j))
{
for (int l=0; l<k; ++l)
{
if (j != l && (i & (1<<l)))
{
cityDist[i][j] = std::min(cityDist[i][j], cityDist[i xor (1<<j)][l] + distances[l][cities[j]]);
}
}
}
}
}
int sol = INF;
for (int i=0; i<k; ++i)
{
sol = std::min(sol, cityDist[(1<<k)-1][i] + distances[i][n-1]);
}
fout << sol << "\n";
fin.close();
fout.close();
return 0;
}