Pagini recente » Cod sursa (job #2793550) | Cod sursa (job #2959779) | Cod sursa (job #3206684) | Cod sursa (job #3282531) | Cod sursa (job #3296938)
// SPDX-License-Identifier: BSD-3-Clause
import java.io.*;
import java.util.*;
public class Main {
static class Task {
public static final String INPUT_FILE = "distante.in";
public static final String OUTPUT_FILE = "distante.out";
static final long INF = Long.MAX_VALUE / 4; // o valoare mare (nu chiar MAX ca să evităm overflow)
static int N, M, S;
static int[] head, to, cost, nxt;
static int edgeCnt;
// Lista de răspunsuri pentru fiecare graf
ArrayList<String> results = new ArrayList<>();
public void solve() {
readInput();
writeOutput();
}
/* ============================ Citire ============================ */
private void readInput() {
try {
Scanner sc = new Scanner(new BufferedReader(new FileReader(INPUT_FILE)));
int T = sc.nextInt(); // numărul de grafuri
for (int t = 0; t < T; t++) {
// 1. Citim numărul de noduri, muchii și sursa
N = sc.nextInt();
M = sc.nextInt();
S = sc.nextInt();
// 2. Citim distanțele date de Bronzarel
long[] given = new long[N + 1];
for (int i = 1; i <= N; i++) {
given[i] = sc.nextLong();
}
// 3. Construim lista de adiacență cu tablouri paralele
head = new int[N + 1];
Arrays.fill(head, -1);
to = new int[2 * M];
cost = new int[2 * M];
nxt = new int[2 * M];
edgeCnt = 0;
// 4. Citim muchiile și le adăugăm bidirecțional (graf neorientat)
for (int i = 0; i < M; i++) {
int u = sc.nextInt(), v = sc.nextInt(), c = sc.nextInt();
addEdge(u, v, c);
addEdge(v, u, c);
}
// 5. Calculăm distanțele cu Dijkstra
long[] dist = dijkstra();
// 6. Verificăm dacă sunt corecte
boolean ok = true;
for (int i = 1; i <= N; i++) {
long di = dist[i] >= INF / 2 ? -1 : dist[i];
if (di != given[i]) {
ok = false;
break;
}
}
// 7. Adăugăm rezultatul în listă
if (ok) {
results.add("DA");
} else {
results.add("NU");
}
}
sc.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/* ============================ Scriere ============================ */
private void writeOutput() {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(OUTPUT_FILE));
for (String line : results) {
bw.write(line);
bw.newLine();
}
bw.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/* ============================ Adăugare muchii ============================ */
static void addEdge(int u, int v, int w) {
to[edgeCnt] = v;
cost[edgeCnt] = w;
nxt[edgeCnt] = head[u];
head[u] = edgeCnt++;
}
/* ============================ Algoritmul Dijkstra ============================ */
static long[] dijkstra() {
long[] dist = new long[N + 1];
Arrays.fill(dist, INF); // inițial toate distanțele sunt "infinite"
dist[S] = 0;
int[] heap = new int[N + 1];
int[] pos = new int[N + 1];
int heapSize = 1;
heap[1] = S;
pos[S] = 1;
// Bucla principală Dijkstra
while (heapSize > 0) {
int u = heap[1];
pos[u] = 0;
heap[1] = heap[heapSize];
pos[heap[1]] = 1;
heapSize--;
heapifyDown(heap, pos, dist, heapSize, 1);
// Relaxăm muchiile lui u
for (int e = head[u]; e != -1; e = nxt[e]) {
int v = to[e];
long nd = dist[u] + cost[e];
if (nd < dist[v]) {
dist[v] = nd;
if (pos[v] == 0) {
heapSize++;
heap[heapSize] = v;
pos[v] = heapSize;
heapifyUp(heap, pos, dist, heapSize);
} else {
heapifyUp(heap, pos, dist, pos[v]);
}
}
}
}
return dist;
}
/* ============================ Heapify pentru Min-Heap ============================ */
static void heapifyUp(int[] heap, int[] pos, long[] dist, int i) {
while (i > 1) {
int p = i >>> 1;
if (dist[heap[p]] <= dist[heap[i]]) break;
swap(heap, pos, p, i);
i = p;
}
}
static void heapifyDown(int[] heap, int[] pos, long[] dist, int heapSize, int i) {
while (true) {
int l = i << 1;
int r = l | 1;
int smallest = i;
if (l <= heapSize && dist[heap[l]] < dist[heap[smallest]]) smallest = l;
if (r <= heapSize && dist[heap[r]] < dist[heap[smallest]]) smallest = r;
if (smallest == i) break;
swap(heap, pos, i, smallest);
i = smallest;
}
}
static void swap(int[] heap, int[] pos, int i, int j) {
int vi = heap[i], vj = heap[j];
heap[i] = vj;
heap[j] = vi;
pos[vi] = j;
pos[vj] = i;
}
}
public static void main(String[] args) {
new Task().solve();
}
}