Problem p03866 (C++)

Buggy submission (status: Runtime Error):
// ====================================
//   author: M_sea
//   website: https://m-sea-blog.com/
// ====================================
#include <bits/stdc++.h>
#define file(x)                                                                \
  freopen(#x ".in", "r", stdin);                                               \
  freopen(#x ".out", "w", stdout)
#define debug(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
typedef long long ll;

int read() {
  int X = 0, w = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-')
      w = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9')
    X = X * 10 + c - '0', c = getchar();
  return X * w;
}

const int N = 1000 + 10, M = 500000 + 10;

int sx, sy, tx, ty, n;
struct circle {
  int x, y, r;
} c[N];

double getdis(int x1, int y1, int x2, int y2) {
  return sqrt(1ll * (x1 - x2) * (x1 - x2) + 1ll * (y1 - y2) * (y1 - y2));
}

struct edge {
  int v;
  double w;
  int nxt;
  edge(int v_ = 0, double w_ = 0, int nxt_ = 0) : v(v_), w(w_), nxt(nxt_) {}
} e[M << 1];
int head[N];
void addEdge(int u, int v, double w) {
  static int cnt = 0;
  e[++cnt] = edge(v, w, head[u]), head[u] = cnt;
}

struct node {
  int u;
  double d;
};
bool operator<(node a, node b) { return a.d > b.d; }
priority_queue<node> Q;
double dis[N];
double dijkstra() {
  memset(dis, 127, sizeof(dis));
  dis[0] = 0;
  Q.push((node){0, 0});
  while (!Q.empty()) {
    int u = Q.top().u;
    double d = Q.top().d;
    Q.pop();
    if (fabs(d - dis[u]) >= 1e-9)
      continue;
    for (int i = head[u]; i; i = e[i].nxt) {
      int v = e[i].v;
      double w = e[i].w;
      if (dis[u] + w < dis[v])
        dis[v] = dis[u] + w, Q.push((node){v, dis[v]});
    }
  }
  return dis[n + 1];
}

int main() {
  sx = read(), sy = read(), tx = read(), ty = read(), n = read();
  for (int i = 1; i <= n; ++i)
    c[i] = (circle){read(), read(), read()};
  c[0] = (circle){sx, sy, 0}, c[n + 1] = (circle){tx, ty, 0};
  for (int i = 0; i <= n; ++i)
    for (int j = i + 1; j <= n + 1; ++j) {
      double w =
          max(0.0, getdis(c[i].x, c[i].y, c[j].x, c[j].y) - c[i].r - c[j].r);
      addEdge(i, j, w), addEdge(j, i, w);
    }
  printf("%.10lf\n", dijkstra());
  return 0;
}

Fixed submission:
// ====================================
//   author: M_sea
//   website: https://m-sea-blog.com/
// ====================================
#include <bits/stdc++.h>
#define file(x)                                                                \
  freopen(#x ".in", "r", stdin);                                               \
  freopen(#x ".out", "w", stdout)
#define debug(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
typedef long long ll;

int read() {
  int X = 0, w = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-')
      w = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9')
    X = X * 10 + c - '0', c = getchar();
  return X * w;
}

const int N = 1000 + 10, M = 1000000 + 10;

int sx, sy, tx, ty, n;
struct circle {
  int x, y, r;
} c[N];

double getdis(int x1, int y1, int x2, int y2) {
  return sqrt(1ll * (x1 - x2) * (x1 - x2) + 1ll * (y1 - y2) * (y1 - y2));
}

struct edge {
  int v;
  double w;
  int nxt;
  edge(int v_ = 0, double w_ = 0, int nxt_ = 0) : v(v_), w(w_), nxt(nxt_) {}
} e[M << 1];
int head[N];
void addEdge(int u, int v, double w) {
  static int cnt = 0;
  e[++cnt] = edge(v, w, head[u]), head[u] = cnt;
}

struct node {
  int u;
  double d;
};
bool operator<(node a, node b) { return a.d > b.d; }
priority_queue<node> Q;
double dis[N];
double dijkstra() {
  memset(dis, 127, sizeof(dis));
  dis[0] = 0;
  Q.push((node){0, 0});
  while (!Q.empty()) {
    int u = Q.top().u;
    double d = Q.top().d;
    Q.pop();
    if (fabs(d - dis[u]) >= 1e-9)
      continue;
    for (int i = head[u]; i; i = e[i].nxt) {
      int v = e[i].v;
      double w = e[i].w;
      if (dis[u] + w < dis[v])
        dis[v] = dis[u] + w, Q.push((node){v, dis[v]});
    }
  }
  return dis[n + 1];
}

int main() {
  sx = read(), sy = read(), tx = read(), ty = read(), n = read();
  for (int i = 1; i <= n; ++i)
    c[i] = (circle){read(), read(), read()};
  c[0] = (circle){sx, sy, 0}, c[n + 1] = (circle){tx, ty, 0};
  for (int i = 0; i <= n; ++i)
    for (int j = i + 1; j <= n + 1; ++j) {
      double w =
          max(0.0, getdis(c[i].x, c[i].y, c[j].x, c[j].y) - c[i].r - c[j].r);
      addEdge(i, j, w), addEdge(j, i, w);
    }
  printf("%.10lf\n", dijkstra());
  return 0;
}