Problem p02949 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

vector<int> dp, path, pathid;
vector<bool> hasloop, touched, reachable;
vector<vector<pair<int, int>>> adj, radj;

#define INF (2000000000)

int p;

// void solve(int id, int step, int d) {
//	if (pathid[id] != -1) {
//		if (d > path[id]) {
//			hasloop[id] = true;
//		}
//		return;
//	}
//
//	dp[id] = max(dp[id], d);
//	if (touched[id]) return;
//
//	touched[id] = true;
//	path[id] = d;
//	pathid[id] = step;
//
//	for (auto p : adj[id]) {
//		solve(p.first, step + 1, d + p.second);
//	}
//
//	path[id] = -INF;
//	pathid[id] = -1;
//
// }

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n, m, a, b, c, i, j, k, id, ans, d;
  cin >> n >> m >> p;
  adj.resize(n + 1);
  radj.resize(n + 1);

  for (i = 0; i < m; i++) {
    cin >> a >> b >> c;
    adj[a].push_back({b, c - p});
    radj[b].push_back({a, c - p});
  }

  dp.assign(n + 1, -INF);
  path.assign(n + 1, -INF);
  pathid.assign(n + 1, -1);
  touched.assign(n + 1, false);
  hasloop.assign(n + 1, false);

  priority_queue<pair<pair<int, int>, vector<int>>> pq;
  pq.push({{0, 1}, path});
  while (!pq.empty()) {
    id = pq.top().first.second;
    d = pq.top().first.first;
    path = pq.top().second;

    pq.pop();
    touched[id] = true;

    if ((path[id] != -INF) && (d > path[id])) {
      hasloop[id] = true;
    } else {
      if ((path[id] == -INF) && (dp[id] < d)) {
        dp[id] = d;
        path[id] = d;
        for (auto p : adj[id])
          pq.push({{d + p.second, p.first}, path});
        path[id] = -INF;
      }
    }
  }

  reachable.assign(n + 1, false);
  queue<int> q;
  q.push(n);
  reachable[n] = true;

  while (!q.empty()) {
    id = q.front();
    q.pop();

    for (auto p : radj[id]) {
      if (!reachable[p.first]) {
        reachable[p.first] = true;
        q.push(p.first);
      }
    }
  }

  bool foundloop = false;
  for (i = 1; i <= n; i++) {
    if (hasloop[i] && reachable[i])
      foundloop = true;
  }

  if (foundloop)
    ans = -1;
  else
    ans = max(0, dp[n]);

  cout << ans << "\n";

  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

vector<int> dp, path, pathid;
vector<bool> hasloop, touched, reachable;
vector<vector<pair<int, int>>> adj, radj;

#define INF (2000000000)

int p;

// void solve(int id, int step, int d) {
//	if (pathid[id] != -1) {
//		if (d > path[id]) {
//			hasloop[id] = true;
//		}
//		return;
//	}
//
//	dp[id] = max(dp[id], d);
//	if (touched[id]) return;
//
//	touched[id] = true;
//	path[id] = d;
//	pathid[id] = step;
//
//	for (auto p : adj[id]) {
//		solve(p.first, step + 1, d + p.second);
//	}
//
//	path[id] = -INF;
//	pathid[id] = -1;
//
// }

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n, m, a, b, c, i, j, k, id, ans, d;
  cin >> n >> m >> p;
  adj.resize(n + 1);
  radj.resize(n + 1);

  for (i = 0; i < m; i++) {
    cin >> a >> b >> c;
    adj[a].push_back({b, c - p});
    radj[b].push_back({a, c - p});
  }

  dp.assign(n + 1, -INF);
  path.assign(n + 1, -INF);
  pathid.assign(n + 1, -1);
  touched.assign(n + 1, false);
  hasloop.assign(n + 1, false);

  priority_queue<pair<pair<int, int>, vector<int>>> pq;
  pq.push({{0, 1}, path});
  while (!pq.empty()) {
    id = pq.top().first.second;
    d = pq.top().first.first;
    path = pq.top().second;

    pq.pop();
    touched[id] = true;

    if ((path[id] != -INF) && (d > path[id])) {
      hasloop[id] = true;
    } else {
      if ((path[id] == -INF) && (dp[id] < d)) {
        dp[id] = d;
        path[id] = d;
        for (auto p : adj[id]) {
          if (dp[p.first] < d + p.second)
            pq.push({{d + p.second, p.first}, path});
        }
        path[id] = -INF;
      }
    }
  }

  reachable.assign(n + 1, false);
  queue<int> q;
  q.push(n);
  reachable[n] = true;

  while (!q.empty()) {
    id = q.front();
    q.pop();

    for (auto p : radj[id]) {
      if (!reachable[p.first]) {
        reachable[p.first] = true;
        q.push(p.first);
      }
    }
  }

  bool foundloop = false;
  for (i = 1; i <= n; i++) {
    if (hasloop[i] && reachable[i])
      foundloop = true;
  }

  if (foundloop)
    ans = -1;
  else
    ans = max(0, dp[n]);

  cout << ans << "\n";

  return 0;
}