Problem p01462 (C++) — buggy submission, verdict: Time Limit Exceeded

#include "cstdio"
#include "cstring"
#include "iostream"
#include "vector"
#define PB push_back
#define MP make_pair
using namespace std;
double p, q;
const int N = 15;
double dp[N][1 << N];
int vis[N][1 << N];
double g[N][1 << N];
int v[1 << N];
double getdp(int x, int y);
double gao(int x) {
  if (__builtin_popcount(x) == 0)
    return 1.0;
  int s = __builtin_ffs(x) - 1;
  return getdp(s, x ^ (1 << s));
}
double qpow(double x, int y) {
  double ans = 1.0;
  while (y != 0) {
    if (y & 1)
      ans = ans * x;
    x = x * x;
    y >>= 1;
  }
  return ans;
}
double getdp(int x, int state) {
  if (vis[x][state])
    return dp[x][state];
  vis[x][state] = 1;
  if (state == 0)
    return dp[x][state] = 1.0;
  int f = __builtin_ffs(state) - 1;
  int s = state ^ (1 << f);
  double sum = 0.0;
  for (int i = s;; i = (i - 1) & s) {
    int tmp = i ^ (1 << f);
    sum += getdp(x, tmp ^ state) * gao(tmp) * g[x][tmp] *
           qpow(q, v[state] - v[tmp] - v[state ^ tmp]);
    if (i == 0)
      break;
  }
  return dp[x][state] = sum;
}
vector<int> edge[N];

int main(void) {
  int n, m, val;
  scanf("%d %d %d", &n, &m, &val);
  q = (double)val / 100.0;
  p = 1.0 - q;
  int x, y;
  for (int i = 1; i <= m; ++i) {
    scanf("%d %d", &x, &y);
    x--;
    y--;
    edge[x].PB(y);
    edge[y].PB(x);
  }
  for (int i = 1; i < (1 << n); ++i) {
    int k = __builtin_ffs(i) - 1;
    v[i] = v[i ^ (1 << k)];
    for (int j = 0; j < edge[k].size(); ++j) {
      int u = edge[k][j];
      if (i & (1 << u)) {
        v[i]++;
      }
    }
    for (int j = 0; j < n; ++j) {
      if (i & (1 << j))
        continue;
      int sum = 0;
      for (int k = 0; k < edge[j].size(); ++k) {
        int u = edge[j][k];
        if (i & (1 << u)) {
          sum++;
        }
      }
      g[j][i] = 1.0 - qpow(q, sum);
    }
  }
  printf("%.12f\\n", gao((1 << n) - 1));
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>

using namespace std;
const int inf = 0x3fffffff;
const double eps = 1e-6;
typedef long long ll;

struct node {
  int s, e;
  double w;
} rec[1000];
int n, m;
double dp[1 << 18];
double dfs(int c) {
  if (dp[c] >= 0)
    return dp[c];
  dp[c] = 0;
  int num = 0, j, a, b, tt, i, pos, state, cur;
  double temp;
  for (i = 0; i < n; i++) {
    if (c & (1 << i))
      pos = i, num++;
  }
  if (num == 1)
    return dp[c] = 1;
  state = c - (1 << pos);
  for (j = (state - 1) & state;; j = (j - 1) & state) {
    cur = j + (1 << pos);
    tt = c - cur;
    temp = 1;
    for (i = 1; i <= m; i++) {
      a = rec[i].s, b = rec[i].e;
      if ((cur & (1 << a)) && (tt & (1 << b)))
        temp *= rec[i].w;
      if ((cur & (1 << b)) && (tt & (1 << a)))
        temp *= rec[i].w;
    }
    dp[c] += temp * dfs(cur);
    if (j == 0)
      break;
  }
  return dp[c] = 1 - dp[c];
}
int main() {
  int t, i, S;
  double p;
  t = 1;
  while (t--) {
    scanf("%d%d%lf", &n, &m, &p);
    for (i = 1; i <= m; i++) {
      scanf("%d%d", &rec[i].s, &rec[i].e), rec[i].s--, rec[i].e--;
      rec[i].w = p / 100;
    }
    S = 1 << n;
    for (i = 0; i < S; i++)
      dp[i] = -1;
    printf("%.13lf\\n", dfs(S - 1));
  }
  return 0;
}