Problem p03405 (C++)

Buggy submission (status: Runtime Error):
#include <climits>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

#define rep(i, i0, n) for (int(i) = (i0); (i) < (n); ++(i))

using namespace std;
using ll = long long;

const ll M = 1e9 + 7;
ll pow2[2020];

vector<pair<int, int>> adj_list[1010];

int pred[1010];
int weights[1010];
bool in_pq[1010];

ll prim(int n, tuple<int, int, int> &e) {
  int w1, u0, u1;
  int u, v, w;
  ll r;

  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      pq;

  fill(pred, pred + n, -1);
  fill(weights, weights + n, INT_MAX);

  tie(w1, u0, u1) = e;

  weights[u0] = weights[u1] = 0;
  pred[u1] = u0;

  rep(v, 0, n) { pq.push(make_pair(weights[v], v)); }

  fill(in_pq, in_pq + n, true);
  in_pq[u0] = in_pq[u1] = false;

  for (int u : {u0, u1}) {
    for (auto p : adj_list[u]) {
      tie(w, v) = p;
      if (in_pq[v]) {
        if (w < weights[v]) {
          pred[v] = u;
          weights[v] = w;
          pq.push(p);
        }
      }
    }
  }

  while (!pq.empty()) {
    auto p = pq.top();
    pq.pop();
    tie(w, u) = p;
    in_pq[u] = false;
    for (auto p : adj_list[u]) {
      tie(w, v) = p;
      if (in_pq[v]) {
        if (w < weights[v]) {
          pred[v] = u;
          weights[v] = w;
          pq.push(p);
        }
      }
    }
  }

  r = w1;
  rep(i, 0, n) { r += weights[i]; }

  return r;
}

int solve(int n, int m, ll x, vector<tuple<int, int, int>> &edges) {
  int s, t;
  ll y, r;
  ll ans;

  s = 0;
  t = 0;
  for (auto e : edges) {
    y = prim(n, e);
    if (y < x) {
      ++s;
    } else if (y == x) {
      ++t;
    }
  }

  if (t == 0) {
    return 0;
  }

  r = 1;
  int mi = max(t, m - s - t + 1) + 1;
  rep(i, 0, mi) {
    pow2[i] = r;
    r <<= 1;
    r %= M;
  }
  if (s == 0) {
    ans = (pow2[t] - 2) * pow2[m - t];
  } else {
    ans = (pow2[t] - 1) * pow2[m - s - t + 1];
  }
  return (int)(ans % M);
}

int main(int argc, const char *argv[]) {

  int n, m;
  int x;
  int u, v, w;
  vector<tuple<int, int, int>> edges;

  cin >> n >> m;
  cin >> x;
  rep(i, 0, m) {
    cin >> u >> v >> w;
    --u;
    --v;
    edges.push_back(make_tuple(w, u, v));
    adj_list[u].push_back(make_pair(w, v));
    adj_list[v].push_back(make_pair(w, u));
  }

  cout << solve(n, m, x, edges) << endl;

  return 0;
}


Fixed submission:
#include <climits>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

#define rep(i, i0, n) for (int(i) = (i0); (i) < (n); ++(i))

using namespace std;
using ll = long long;

const ll M = 1e9 + 7;
ll pow2[2020];

vector<pair<int, int>> adj_list[1010];

int pred[1010];
int weights[1010];
bool in_pq[1010];

ll prim(int n, tuple<int, int, int> &e) {
  int w1, u0, u1;
  int u, v, w;
  ll r;

  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      pq;

  fill(pred, pred + n, -1);
  fill(weights, weights + n, INT_MAX);

  tie(w1, u0, u1) = e;

  weights[u0] = weights[u1] = 0;
  pred[u1] = u0;

  rep(v, 0, n) { pq.push(make_pair(weights[v], v)); }

  fill(in_pq, in_pq + n, true);
  in_pq[u0] = in_pq[u1] = false;

  for (int u : {u0, u1}) {
    for (auto p : adj_list[u]) {
      tie(w, v) = p;
      if (in_pq[v]) {
        if (w < weights[v]) {
          pred[v] = u;
          weights[v] = w;
          pq.push(p);
        }
      }
    }
  }

  while (!pq.empty()) {
    auto p = pq.top();
    pq.pop();
    tie(w, u) = p;
    in_pq[u] = false;
    for (auto p : adj_list[u]) {
      tie(w, v) = p;
      if (in_pq[v]) {
        if (w < weights[v]) {
          pred[v] = u;
          weights[v] = w;
          pq.push(p);
        }
      }
    }
  }

  r = w1;
  rep(i, 0, n) { r += weights[i]; }

  return r;
}

int solve(int n, int m, ll x, vector<tuple<int, int, int>> &edges) {
  int s, t;
  ll y, r;
  ll ans;

  s = 0;
  t = 0;
  for (auto e : edges) {
    y = prim(n, e);
    if (y < x) {
      ++s;
    } else if (y == x) {
      ++t;
    }
  }

  if (t == 0) {
    return 0;
  }

  r = 1;
  int mi = max(t, m - s - t + 1) + 1;
  rep(i, 0, mi) {
    pow2[i] = r;
    r <<= 1;
    r %= M;
  }
  if (s == 0) {
    ans = (pow2[t] - 2) * pow2[m - t];
  } else {
    ans = (pow2[t] - 1) * pow2[m - s - t + 1];
  }
  return (int)(ans % M);
}

int main(int argc, const char *argv[]) {

  int n, m;
  ll x;
  int u, v, w;
  vector<tuple<int, int, int>> edges;

  cin >> n >> m;
  cin >> x;
  rep(i, 0, m) {
    cin >> u >> v >> w;
    --u;
    --v;
    edges.push_back(make_tuple(w, u, v));
    adj_list[u].push_back(make_pair(w, v));
    adj_list[v].push_back(make_pair(w, u));
  }

  cout << solve(n, m, x, edges) << endl;

  return 0;
}