Problem p03664 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <map>
#include <memory.h>
#include <queue>
#include <string>
#include <vector>
#define ll int
#define For(i, j, k) for (ll i = j; i <= k; ++i)
#define FOr(i, j, k) for (ll i = j; i >= k; --i)
#define ld double
using namespace std;
inline ll read() {
  ll x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void wrote(ll x) {
  if (x < 0)
    putchar('-'), x = -x;
  if (x >= 10)
    wrote(x / 10);
  putchar(x % 10 + '0');
}
inline void writeln(ll x) {
  wrote(x);
  puts("");
}
const ll sz = (1 << 15), N = 16;
ll n, m, f[sz][N], g[sz][N], mp[N][N], cur[sz];
int main() {
  freopen("a.in", "r", stdin);
  n = read();
  m = read();
  while (m--) {
    ll x = read() - 1, y = read() - 1, w = read();
    mp[x][y] = mp[y][x] = w;
  }
  For(i, 0, n - 1) cur[1 << i] = i;
  ll all = (1 << n) - 1;
  For(S, 0, all) For(i, 0, n - 1) if ((S >> i) & 1) For(j, 0, n - 1) f[S][j] +=
      mp[i][j]; // S->j所有路
  memset(g, 60, sizeof g);
  For(S, 1, all) g[S][0] = 0;
  For(S, 1, all)
      For(i, 0, n - 1) if ((S >> i) & 1) for (ll T = all ^ S; T;
                                              T = (T - 1) & (all ^ S)) {
    ll ans = 0;
    for (ll j = T; j; j -= j & -j)
      ans += f[S][cur[j & -j]];
    if ((T >> (n - 1)) & 1) {
      if (mp[i][n - 1])
        g[S | T][n - 1] = min(g[S | T][n - 1], g[S][i] + ans - mp[i][n - 1]);
    } else
      For(j, 0, n - 1) if (mp[i][j] && ((T >> j) & 1)) g[S | T][j] =
          min(g[S | T][j], g[S][i] + ans - mp[i][j]);
  }
  ll answ = 1e9 + 7;
  For(S, 1, all) {
    ll T = S ^ all, ans = 0;
    For(i, 0, n - 1) if ((T >> i) & 1) ans += f[S][i];
    answ = min(answ, ans + g[S][n - 1]);
  }
  writeln(answ);
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <map>
#include <memory.h>
#include <queue>
#include <string>
#include <vector>
#define ll int
#define For(i, j, k) for (ll i = j; i <= k; ++i)
#define FOr(i, j, k) for (ll i = j; i >= k; --i)
#define ld double
using namespace std;
inline ll read() {
  ll x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void wrote(ll x) {
  if (x < 0)
    putchar('-'), x = -x;
  if (x >= 10)
    wrote(x / 10);
  putchar(x % 10 + '0');
}
inline void writeln(ll x) {
  wrote(x);
  puts("");
}
const ll sz = (1 << 15), N = 16;
ll n, m, f[sz][N], g[sz][N], mp[N][N], cur[sz];
int main() {
  //	freopen("a.in","r",stdin);
  n = read();
  m = read();
  while (m--) {
    ll x = read() - 1, y = read() - 1, w = read();
    mp[x][y] = mp[y][x] = w;
  }
  For(i, 0, n - 1) cur[1 << i] = i;
  ll all = (1 << n) - 1;
  For(S, 0, all) For(i, 0, n - 1) if ((S >> i) & 1) For(j, 0, n - 1) f[S][j] +=
      mp[i][j]; // S->j所有路
  memset(g, 60, sizeof g);
  For(S, 1, all) g[S][0] = 0;
  For(S, 1, all)
      For(i, 0, n - 1) if ((S >> i) & 1) for (ll T = all ^ S; T;
                                              T = (T - 1) & (all ^ S)) {
    ll ans = 0;
    for (ll j = T; j; j -= j & -j)
      ans += f[S][cur[j & -j]];
    if ((T >> (n - 1)) & 1) {
      if (mp[i][n - 1])
        g[S | T][n - 1] = min(g[S | T][n - 1], g[S][i] + ans - mp[i][n - 1]);
    } else
      For(j, 0, n - 1) if (mp[i][j] && ((T >> j) & 1)) g[S | T][j] =
          min(g[S | T][j], g[S][i] + ans - mp[i][j]);
  }
  ll answ = 1e9 + 7;
  For(S, 1, all) {
    ll T = S ^ all, ans = 0;
    For(i, 0, n - 1) if ((T >> i) & 1) ans += f[S][i];
    answ = min(answ, ans + g[S][n - 1]);
  }
  writeln(answ);
}