Problem p02698 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <climits>
#include <cmath>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <unordered_set>
#include <vector>

using namespace std;
typedef long long ll;

struct NODE {
  vector<ll> children;
  ll a;
  ll ans;
};

NODE nodes[200001];
ll dp[200001];
ll N;
void DFS(int node, int parent) {
  ll temp = *lower_bound(dp, dp + N, nodes[node].a);
  *lower_bound(dp, dp + N, nodes[node].a) = nodes[node].a;
  nodes[node].ans = lower_bound(dp, dp + N, LLONG_MAX) - dp;

  for (int i = 0; i < nodes[node].children.size(); i++) {
    if (nodes[node].children[i] != parent) {
      DFS(nodes[node].children[i], node);
    }
  }
  *lower_bound(dp, dp + N, nodes[node].a) = temp; // DPの状態をもとに戻す
}

int main() {
  cin >> N;
  for (int i = 1; i <= N; i++) {
    cin >> nodes[i].a;
  }
  for (int i = 0; i < N - 1; i++) {
    int u, v;
    cin >> u >> v;
    nodes[u].children.push_back(v);
    nodes[v].children.push_back(u);
  }
  fill(dp, dp + N, LLONG_MAX);
  DFS(1, 0);
  for (int i = 1; i <= N; i++) {
    cout << nodes[i].ans << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <climits>
#include <functional>
#include <iostream>
#include <math.h>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <unordered_set>
#include <vector>

using namespace std;
typedef long long ll;

struct Edge;
struct Node {
  ll cost;
  bool isClosed;
  vector<Edge *> edges;
  Node *last;
  ll a;

  Node() {}
};

struct NODE {
  Node *node;
  ll costWhenPushed;
  bool operator<(const NODE &rhs) const {
    return costWhenPushed > rhs.costWhenPushed;
  } // 逆にする
  NODE(Node *n, ll cost) {
    node = n;
    costWhenPushed = cost;
  }
};

struct Edge {
  Node *node0;
  Node *node1;
  ll cost;
};

vector<Node> Nodes;
vector<Edge> Edges;

ll Dijkstra_Find(Node *s, Node *g) {
  // 初期化
  for (int i = 0; i < Nodes.size(); i++) {
    Nodes[i].cost = &Nodes[i] == s ? 0 : LLONG_MAX / 2;
    Nodes[i].isClosed = false;
    Nodes[i].last = nullptr;
  }
  priority_queue<NODE> que;
  que.push(NODE(s, 0));

  while (!que.empty()) {
    Node *n = que.top().node;
    ll costWhenPushed = que.top().costWhenPushed;
    que.pop();
    if (n->cost < costWhenPushed) {
      continue;
    }
    n->isClosed = true;

    int size = (n->edges).size();
    for (int i = 0; i < size; i++) {
      Node *processNode = (n->edges)[i]->node0 == n ? (n->edges)[i]->node1
                                                    : (n->edges)[i]->node0;
      if (processNode->isClosed) {
        continue;
      }

      ll newCost = n->cost + (n->edges)[i]->cost;
      if (newCost < processNode->cost) {
        processNode->cost = newCost;
        processNode->last = n;
        que.push(NODE(processNode, newCost));
      }
    }
  }

  return g->cost;
}

int main() {
  int N;
  cin >> N;
  for (int i = 0; i <= N; i++) {
    Node node;
    Edge edge;
    edge.cost = 1;
    Nodes.push_back(node);
    Edges.push_back(edge);
  }

  for (int i = 0; i < N; i++) {
    cin >> Nodes[i + 1].a;
  }
  for (int i = 1; i < N; i++) {
    int u, v;
    cin >> u >> v;
    Edge *edge = &Edges[i];
    Node *nodeU = &Nodes[u];
    Node *nodeV = &Nodes[v];
    edge->node0 = nodeU;
    edge->node1 = nodeV;
    nodeU->edges.push_back(edge);
    nodeV->edges.push_back(edge);
  }

  Dijkstra_Find(&Nodes[1], &Nodes[N]);

  for (int i = 1; i <= N; i++) {
    Node *curNode = &Nodes[i];
    vector<ll> line;
    while (curNode != nullptr) {
      line.push_back(curNode->a);
      curNode = curNode->last;
    }

    vector<ll> lineBack;
    for (int i = 0; i < line.size(); i++) {
      lineBack.push_back(line[line.size() - 1 - i]);
    }

    // 最長増加部分列問題のDP
    ll dp[100000];
    int n = lineBack.size();
    fill(dp, dp + n, LONG_MAX / 2);
    for (int i = 0; i < n; ++i) {
      *lower_bound(dp, dp + n, lineBack[i]) = lineBack[i];
    }
    cout << lower_bound(dp, dp + n, LONG_MAX / 2) - dp << endl;
  }

  return 0;
}