Pagini recente » Cod sursa (job #1372807) | Cod sursa (job #2256151) | Cod sursa (job #366549) | Cod sursa (job #3121949) | Cod sursa (job #3128069)
#include <fstream>
#include <vector>
#define NMAX 50000
using namespace std;
ifstream f("distante.in");
ofstream g("distante.out");
class Task {
public:
void solve() {
read_input();
print_output(dijkstra());
}
private:
// n = numar de noduri, m = numar de muchii
int n, m;
// adj[node] = lista de adiacenta a nodului node
// perechea (neigh, w) semnifica arc de la node la neigh de cost w
vector<pair<int, int>> adj[NMAX];
vector<int> distBronz;
// nodul sursa
int source;
void read_input() {
f >> n >> m >> source;
distBronz.push_back(-1); // indexing from 1
for (int i = 1, d; i <= n; ++i)
f >> d, distBronz.push_back(d);
for (int i = 1, x, y, w; i <= m; i++) {
f >> x >> y >> w;
adj[x].push_back({y, w});
adj[y].push_back({x, w});
}
}
#define popMin(heap, heapLen, dist, poz) pop(heap, heapLen, dist, poz, 1)
int pop(vector<int> &heap,int &heapLen,vector<int> &dist,vector<int> &poz,int nod)
{
int ret = heap[nod], last = heap[heapLen--];
while (2 * nod <= heapLen)
if (dist[last] > dist[heap[2 * nod]])
heap[nod] = heap[2 * nod], poz[heap[nod]] = nod, nod *= 2;
else if (2 * nod + 1 <= heapLen && dist[last] > dist[heap[2 * nod + 1]])
heap[nod] = heap[2 * nod + 1], poz[heap[nod]] = nod, nod = 2 * nod + 1;
else break;
heap[nod] = last;
poz[last] = nod;
poz[ret] = -1;
return ret;
}
void update(vector<int> &heap, int &heapLen, vector<int> &dist, vector<int> &poz, int nod)
{
int last = heap[nod];
while (nod > 1)
if (dist[last] < dist[heap[nod / 2]])
heap[nod] = heap[nod / 2], poz[heap[nod]] = nod,nod /= 2;
else break;
heap[nod] = last;
poz[last] = nod;
}
bool dijkstra() {
vector<int> d(n + 1, -1);
vector<int> p(n + 1, -1);
vector<int> heap(n + 1);
int heapLen=1;
heap[heapLen]=source;
p[source]=heapLen;
d[source]=0;
while (heapLen) {
int node = popMin(heap, heapLen, d, p);
for(auto& [neigh, w] : adj[node])
if(d[neigh] == -1 || d[neigh] > d[node] + w)
{
d[neigh] = d[node] + w;
if (d[neigh] < distBronz[neigh])
return false;
if (p[neigh] == -1)
{
heap[++heapLen] = neigh;
p[neigh] = heapLen;
}
update(heap, heapLen, d, p, p[neigh]);
}
}
return true;
}
void print_output(bool ok) {
g << (ok?"DA":"NU") << '\n';
}
};
int main() {
int T;
f >> T;
for (int i = 0; i < T; ++i) {
auto* task = new (nothrow) Task();
task->solve();
delete task;
}
f.close();
g.close();
}