Problem p03405 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
using namespace std;
#define MOD (long long int)(1e9 + 7)
#define ll long long int
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, n) for (int i = 1; i <= (int)(n); i++)
#define REP(i, n) for (int i = n - 1; i >= 0; i--)
#define REPS(i, n) for (int i = n; i > 0; i--)
#define INF (int)(1123456789)
#define LINF (long long int)(112345678901234567)
#define chmax(a, b) a = (((a) < (b)) ? (b) : (a))
#define chmin(a, b) a = (((a) > (b)) ? (b) : (a))
#define all(v) v.begin(), v.end()

const int N = (int)3e5;

ll mpow(ll a, ll b) {
  if (b == 0)
    return 1;
  else if (b % 2 == 0) {
    ll memo = mpow(a, b / 2);
    return memo * memo % MOD;
  } else
    return mpow(a, b - 1) * a % MOD;
}
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
vector<ll> kaijo_memo;
ll kaijo(ll n) {
  if (kaijo_memo.size() > n)
    return kaijo_memo[n];
  if (kaijo_memo.size() == 0)
    kaijo_memo.push_back(1);
  while (kaijo_memo.size() <= n)
    kaijo_memo.push_back(kaijo_memo[kaijo_memo.size() - 1] * kaijo_memo.size() %
                         MOD);
  return kaijo_memo[n];
}
ll nCr(ll n, ll r) {
  if (n < r || r < 0)
    return 0;
  ll ret = 1;
  ret *= kaijo(n);
  ret %= MOD;
  ret *= mpow(kaijo(r), MOD - 2);
  ret %= MOD;
  ret *= mpow(kaijo(n - r), MOD - 2);
  ret %= MOD;
  return ret;
}

int p[1100];
int find(int a) {
  if (p[a] == a) {
    return a;
  } else {
    return p[a] = find(p[a]);
  }
}
void unite(int a, int b) {
  int pa = find(a);
  int pb = find(b);
  p[pa] = pb;
}

struct edge {
  ll cost, a, b;
};
int n, m;
vector<edge> E;

ll prim(int ei) {
  ll ret = 0;
  rep(i, n) { p[i] = i; }
  ret += E[ei].cost;
  unite(E[ei].a, E[ei].b);
  rep(i, E.size()) {
    edge e = E[i];
    ll cost = e.cost;
    ll a = e.a;
    ll b = e.b;
    cerr << a << " " << find(a) << " " << b << " " << find(b) << endl;
    if (find(a) != find(b)) {
      unite(a, b);
      ret += cost;
    }
  }
  return ret;
}

int main(void) {
  cin >> n >> m;
  ll x;
  cin >> x;
  rep(i, m) {
    ll u, v, w;
    cin >> u >> v >> w;
    u--;
    v--;
    E.push_back({w, u, v});
  }
  sort(all(E), [](const edge &x, const edge &y) { return x.cost < y.cost; });
  ll equal = 0, over = 0, under = 0;
  rep(i, E.size()) {
    ll ret = prim(i);
    if (ret == x) {
      equal++;
    } else if (ret < x) {
      under++;
    } else {
      over++;
    }
  }
  // over どっちでもいい
  // equal どれかは黒
  // under 必ず白
  cerr << under << " " << equal << " " << over << endl;
  ll ans = (under == 0 ? 1 : 2) *
           max((ll)0, (mpow(2, equal) - 1 - (under == 0 ? 1 : 0))) % MOD *
           mpow(2, over) % MOD;
  cout << ans << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
using namespace std;
#define MOD (long long int)(1e9 + 7)
#define ll long long int
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, n) for (int i = 1; i <= (int)(n); i++)
#define REP(i, n) for (int i = n - 1; i >= 0; i--)
#define REPS(i, n) for (int i = n; i > 0; i--)
#define INF (int)(1123456789)
#define LINF (long long int)(112345678901234567)
#define chmax(a, b) a = (((a) < (b)) ? (b) : (a))
#define chmin(a, b) a = (((a) > (b)) ? (b) : (a))
#define all(v) v.begin(), v.end()

const int N = (int)3e5;

ll mpow(ll a, ll b) {
  if (b == 0)
    return 1;
  else if (b % 2 == 0) {
    ll memo = mpow(a, b / 2);
    return memo * memo % MOD;
  } else
    return mpow(a, b - 1) * a % MOD;
}
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
vector<ll> kaijo_memo;
ll kaijo(ll n) {
  if (kaijo_memo.size() > n)
    return kaijo_memo[n];
  if (kaijo_memo.size() == 0)
    kaijo_memo.push_back(1);
  while (kaijo_memo.size() <= n)
    kaijo_memo.push_back(kaijo_memo[kaijo_memo.size() - 1] * kaijo_memo.size() %
                         MOD);
  return kaijo_memo[n];
}
ll nCr(ll n, ll r) {
  if (n < r || r < 0)
    return 0;
  ll ret = 1;
  ret *= kaijo(n);
  ret %= MOD;
  ret *= mpow(kaijo(r), MOD - 2);
  ret %= MOD;
  ret *= mpow(kaijo(n - r), MOD - 2);
  ret %= MOD;
  return ret;
}

int p[1100];
int find(int a) {
  if (p[a] == a) {
    return a;
  } else {
    return p[a] = find(p[a]);
  }
}
void unite(int a, int b) {
  int pa = find(a);
  int pb = find(b);
  p[pa] = pb;
}

struct edge {
  ll cost, a, b;
};
int n, m;
vector<edge> E;

ll prim(int ei) {
  ll ret = 0;
  rep(i, n) { p[i] = i; }
  ret += E[ei].cost;
  unite(E[ei].a, E[ei].b);
  rep(i, E.size()) {
    edge e = E[i];
    ll cost = e.cost;
    ll a = e.a;
    ll b = e.b;
    if (find(a) != find(b)) {
      unite(a, b);
      ret += cost;
    }
  }
  return ret;
}

int main(void) {
  cin >> n >> m;
  ll x;
  cin >> x;
  rep(i, m) {
    ll u, v, w;
    cin >> u >> v >> w;
    u--;
    v--;
    E.push_back({w, u, v});
  }
  sort(all(E), [](const edge &x, const edge &y) { return x.cost < y.cost; });
  ll equal = 0, over = 0, under = 0;
  rep(i, E.size()) {
    ll ret = prim(i);
    if (ret == x) {
      equal++;
    } else if (ret < x) {
      under++;
    } else {
      over++;
    }
  }
  // over どっちでもいい
  // equal どれかは黒
  // under 必ず白
  cerr << under << " " << equal << " " << over << endl;
  ll ans = (under == 0 ? 1 : 2) *
           max((ll)0, (mpow(2, equal) - 1 - (under == 0 ? 1 : 0))) % MOD *
           mpow(2, over) % MOD;
  cout << ans << endl;
  return 0;
}