Pagini recente » Cod sursa (job #923809) | Cod sursa (job #525660) | Cod sursa (job #2890182) | Cod sursa (job #1905043) | Cod sursa (job #1594245)
#include<iostream>
#include<fstream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<bitset>
#include<cstring>
#include<queue>
#include<stack>
#define ull unsigned long long
#define ll long long
#define pb push_back
#define FOR(a,b,c) for (int a=b;a<=c; ++a)
#define ROF(a,b,c) for (int a=b;a>=c; --a)
#define Nmax 2100
#define Kmax 20
#define inf 1900900900
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
int N,M,K;
int d[Nmax],ord_oras[Nmax],dist[Kmax][Kmax],dp[1<<Kmax][Kmax];
// d[i]=distanta de la un nod sursa la nodul i dupa o iterare a algoritmului dijkstra
// ord_oras[i]=numarul de ordine al nodului i in noul graf
// dist[i][j]=distanta de la nodul i la nodul j in noul graf
// dp[i][j]=distanta minima de la nodul sursa la nodul j de masca i in noul graf
vector<int> orase;
// vector ce retine orasele in care locuiesc prietenii ubuntzeilor
struct elem2 {
int x,cost;
};
vector<elem2> edge[Nmax]; // edge[i]=lista nodurilor adiacente nodului i
priority_queue<elem2> heap; // heap pentru dijkstra
bool operator <(const elem2 a, const elem2 b) {
return a.cost>b.cost;
}
void dijkstra(int);
int main()
{
f>>N>>M>>K;
const int sursa=1;
const int dest=N;
orase.pb(sursa);
ord_oras[sursa]=orase.size()-1;
FOR (i,1,K) {
int x;
f>>x;
orase.pb(x);
ord_oras[x]=orase.size()-1;
}
orase.pb(dest);
ord_oras[dest]=orase.size()-1;
FOR (i,1,M) {
int x,y,cost;
f>>x>>y>>cost;
elem2 A;
A.x=y;
A.cost=cost;
edge[x].pb(A);
A.x=x;
edge[y].pb(A);
}
dijkstra(sursa);
if (!K) {
g<<d[dest];
return 0;
}
// se va crea un graf nou, format din sursa, destinatie si orasele ce contin prieteni
vector<int>::iterator it;
for (it=orase.begin(),++it;it<orase.end();++it) {
dist[ord_oras[sursa]][ord_oras[*it]]=d[*it];
}
for (it=orase.begin(),++it;it<orase.end()-1;++it) {
dijkstra(*it);
vector<int>::iterator vecin;
for (vecin=orase.begin();vecin<orase.end();++vecin) {
if ((*it)!=(*vecin)) {
dist[ord_oras[*it]][ord_oras[*vecin]]=d[*vecin];
}
}
}
// programare dinamica
for (int i=1;i<(1<<orase.size());++i) {
int ok=0;
for (int j=0;j<orase.size();++j) {
if (i==(1<<j)) {
dp[i][j]=dist[ord_oras[sursa]][j];
ok=1;
break;
}
}
if (ok) {
continue;
}
for (int j=0;j<orase.size();++j) {
dp[i][j]=inf;
if (i & (1<<j)) {
for (int k=0;k<orase.size();++k) {
if (j!=k && (i & (1<<k))) {
if (dp[i][j]>dp[i-(1<<j)][k]+dist[k][j]) {
dp[i][j]=dp[i-(1<<j)][k]+dist[k][j];
}
}
}
}
}
}
g<<dp[(1<<orase.size())-1][ord_oras[dest]];
f.close();g.close();
return 0;
}
void dijkstra(int src) {
FOR (i,1,N) {
d[i]=inf;
}
d[src]=0;
elem2 A;
A.x=src;
A.cost=0;
heap.push(A);
while (!heap.empty()) {
A=heap.top();
heap.pop();
int nod=A.x;
int cost=A.cost;
if (d[nod]<cost) {
continue;
}
vector<elem2>::iterator it;
for (it=edge[nod].begin();it<edge[nod].end();++it) {
int vecin=(*it).x;
if (d[vecin]>d[nod]+(*it).cost) {
d[vecin]=d[nod]+(*it).cost;
A.x=vecin;
A.cost=d[vecin];
heap.push(A);
}
}
}
}