Pagini recente » Cod sursa (job #1595740) | Cod sursa (job #1856579) | Cod sursa (job #1030714) | Statistici Tocila Andrei (AndreiTocila) | Cod sursa (job #1122056)
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
ifstream in ("ubuntzei.in");
ofstream out ("ubuntzei.out");
const int N = 10005;
const int INF = 200000000;
const int K = 20;
struct Muchie {
int nod;
int cost;
};
int noduri, muchii;
int nodAdaugat;
int numarTreceri[N];
int cost[N];
int graf2[K][K];
int d[131072][K];
vector <int> deVizitat;
vector <Muchie> a[N];
Muchie getMuchie(int a, int b)
{
Muchie m;
m.nod = a;
m.cost = b;
return m;
}
int minim (int a, int b)
{
return a < b ? a : b;
}
void read()
{
in >> noduri >> muchii;
int k;
in >> k;
for (int i = 1; i <= k; i++) {
int x;
in >> x;
deVizitat.push_back(x);
}
for (int i = 1; i <= muchii; i++) {
int x, y, z;
in >> x >> y >> z;
a[x].push_back(getMuchie(y, z));
a[y].push_back(getMuchie(x, z));
}
}
void initializeaza()
{
for (int i = 1; i <= noduri; ++i) {
numarTreceri[i] = 0;
cost[i] = INF;
}
}
void cicluHamilton()
{
int numarVarfuri = deVizitat.size() + 2;
for (int i = 1; i < numarVarfuri; ++i) {
d[1][i] = INF;
}
int numarPermutari = (1 << numarVarfuri) - 1;
for (int i = 3; i <= numarPermutari; i += 2) {
d[i][0] = INF;
for (int j = 1; j < numarVarfuri; ++j) {
d[i][j] = INF;
int j2 = (1 << j);
if (i & j2) {
int iprim = i ^ j2;
for (int k = 0; k < numarVarfuri; ++k) {
int k2 = (1 << k);
if (graf2[k][j] != 0 and (iprim & k2) and (j != k)) {
d[i][j] = minim (d[i][j], d[iprim][k] + graf2[k][j]);
}
}
}
}
}
int sol = INF;
for (int i = 1; i <= numarVarfuri; ++i) {
if (graf2[i][0] != 0) {
sol = minim (sol, d[numarPermutari][i] + graf2[i][numarVarfuri-1]);
}
}
out << sol << "\n";
}
void bfd(int nod)
{
queue <int> coada;
initializeaza();
cost[nod] = 0;
coada.push(nod);
while(!coada.empty()) {
int nodVechi = coada.front();
int costVechi = cost[nodVechi];
coada.pop();
for (int i = 0; i < a[nodVechi].size(); ++i) {
int nodNou = a[nodVechi][i].nod;
int costNou = a[nodVechi][i].cost;
if (cost[nodNou] > costNou + costVechi) {
numarTreceri[nodNou]++;
if (numarTreceri[nodNou] >= noduri) {
return;
}
coada.push(nodNou);
cost[nodNou] = costNou + costVechi;
}
}
}
// construiesc noul graf
if (nod != 1) {
graf2[nodAdaugat][0] = cost[1];
}
for (int i = 0; i < deVizitat.size(); ++i) {
if (deVizitat[i] != nod) {
graf2[nodAdaugat][i+1] = cost[deVizitat[i]];
}
}
if (nod != noduri) {
graf2[nodAdaugat][deVizitat.size()+1] = cost[noduri];
}
nodAdaugat++;
}
void solve()
{
bfd(1);
for (int index = 0; index < deVizitat.size(); ++index) {
bfd(deVizitat[index]);
}
bfd(noduri);
cicluHamilton();
}
int main()
{
read();
solve();
return 0;
}