Turista želi da putuje od grada \(A\) do grada \(B\). Na svom putu on želi da poseti barem jedan od gradova \(C\) i \(D\). Kako je turista štedljiv i hoće da uštedi gorivo, želi da putuje najkraćim mogućim putem.
Napisati program koji računa dužinu najkraćeg puta koji turista može da izabere.
Sa standardnog ulaza se unose prirodni brojevi \(n\) (\(1 \leq n \leq 100\)) i \(m\) (\(1 \leq m \leq 10000\)) koji predstavljaju broj gradova i broj puteva među njima. Nakon toga se u sledećih \(m\) redova unose po tri prirodna broja \(X\ Y\ d\), pri čemu su \(X\) i \(Y\) krajevi jednog puta, a \(d\) njegova dužina. Nakon toga se u novom redu unose prirodni brojevi \(A\), \(B\), \(C\) i \(D\) koji označavaju gradove iz teksta zadatka.
Na standardni izlaz ispisati dužinu najkraćeg puta između gradova \(A\) i \(B\) koji posećuje barem jedan od gradova \(C\) i \(D\).
7 11 0 1 4 0 5 7 0 6 2 1 2 10 1 6 3 2 3 8 2 6 11 3 4 9 4 5 6 4 6 1 5 6 5 0 3 1 5
17
U pitanju je putanja 0-1-6-4-3
U ovom bloku se opisuje glavno rešenje zadatka.
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <limits>
#define INFINITY numeric_limits<int>::max()
using namespace std;
struct poredjenje
{
bool operator()(const pair<int, int> &p1, const pair<int, int> &p2)
{
return p1.first > p2.first;
}
};
class Graph {
private:
int broj_cvorova;
vector<vector<pair<int, int>>> lista_suseda;
vector<int> udaljenosti;
vector<bool> nadjeni_putevi;
public:
Graph(int broj_cvorova) {
this->broj_cvorova = broj_cvorova;
lista_suseda.resize(broj_cvorova);
udaljenosti.resize(broj_cvorova, INFINITY);
nadjeni_putevi.resize(broj_cvorova, false);
}
void dodaj_granu(int u, int v, int w) {
lista_suseda[u].push_back({v, w});
lista_suseda[v].push_back({u, w});
}
void resetuj_graf() {
fill(udaljenosti.begin(), udaljenosti.end(), INFINITY);
fill(nadjeni_putevi.begin(), nadjeni_putevi.end(), false);
}
int dijkstra(int u, int v) {
priority_queue<pair<int, int>, vector<pair<int, int>>, poredjenje> hip;
udaljenosti[u] = 0;
hip.push(make_pair(udaljenosti[u], u));
pair<int, int> tmp;
while (!hip.empty()) {
tmp = hip.top();
hip.pop();
if (nadjeni_putevi[tmp.second]) {
continue;
}
nadjeni_putevi[tmp.second] = true;
for (pair<int, int> &sused : lista_suseda[tmp.second]) {
if (udaljenosti[sused.first] > udaljenosti[tmp.second] + sused.second) {
udaljenosti[sused.first] = udaljenosti[tmp.second] + sused.second;
hip.push(make_pair(udaljenosti[sused.first], sused.first));
}
}
}
return udaljenosti[v];
}
int najjeftiniji_let(int u, int v, int dest1, int dest2) {
resetuj_graf();
int u_dest1 = dijkstra(u, dest1);
resetuj_graf();
int dest1_v = dijkstra(dest1, v);
int rezultat1 = u_dest1 + dest1_v;
resetuj_graf();
int u_dest2 = dijkstra(u, dest2);
resetuj_graf();
int dest2_v = dijkstra(dest2, v);
int rezultat2 = u_dest2 + dest2_v;
return min(rezultat1, rezultat2);
}
};
int main ()
{
int n, m;
cin >> n >> m;
Graph *G = new Graph(n);
int u, v, w;
for (int i = 0; i < m; i++) {
cin >> u >> v >> w;
G->dodaj_granu(u, v, w);
}
int a, b, dest1, dest2;
cin >> a >> b >> dest1 >> dest2;
cout << G->najjeftiniji_let(a, b, dest1, dest2) << "\n";
delete G;
return 0;
}