Problem p01347 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define all(x) (x).begin(), (x).end()
#define size(x) ((int)(x).size())
#define FIRST first
#define SECOND second
#define FRONT front
#define PUSH_BACK push_back
#define MAKE_PAIR make_pair
#define EMPTY empty
#define PRIORITY_QUEUE priority_queue
using namespace std;
typedef long long LL;
typedef unsigned int uii;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
// head

const int maxn = 123;
int vin[maxn], vout[maxn];
const int inf = 1e8;
int len[maxn];
struct edge {
  int v, r, w, c;
};
std::vector<edge> G[maxn];
int h[maxn], dist[maxn];
int pv[maxn], pe[maxn];
int V;
std::vector<pii> d[maxn];
int DAG_longest_path(int u, int t) {
  if (u == t || len[u])
    return len[u];
  for (auto e : d[u]) {
    len[u] = max(len[u], e.second + DAG_longest_path(e.first, t));
  }
  return len[u];
}

void add(int u, int v, int w, int cost) {
  G[u].push_back((edge){v, size(G[v]), w, cost});
  G[v].push_back((edge){u, size(G[u]) - 1, 0, -cost});
}

int min_cost_flow(int s, int t, int flow) {
  int res = 0;
  fill(h, h + V, 0);
  while (flow > 0) {
    fill(dist, dist + V, inf);
    dist[s] = 0;
    priority_queue<pii, std::vector<pii>, greater<pii>> q;
    q.push(pii(0, s));
    while (!q.empty()) {
      pii x = q.top();
      q.pop();
      int u = x.second;
      if (dist[u] < x.first)
        continue;
      for (int i = 0; i < size(G[u]); i++) {
        edge &e = G[u][i];
        int k = h[u] + dist[u] + e.c - h[e.v];
        if (k < dist[e.v] && e.w > 0) {
          dist[e.v] = k;
          q.push(pii(k, e.v));
          pv[e.v] = u;
          pe[e.v] = i;
        }
      }
    }
    if (dist[t] == inf) {
      return -1; // 不能再增广
    }
    for (int i = 0; i < V; i++) {
      h[i] += dist[i];
    }
    int tf = flow;
    for (int v = t; v != s; v = pv[v]) {
      tf = min(tf, G[pv[v]][pe[v]].w);
    }
    if (tf) {
      for (int v = t; v != s; v = pv[v]) {
        edge &e = G[pv[v]][pe[v]];
        e.w -= tf;
        G[v][e.r].w += tf;
      }
      res += tf * h[t];
      flow -= tf;
    }
  }
  return res;
}

int main(int argc, char const *argv[]) {
#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  int tot = 0;
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    vin[v]++, vout[u]++;
    d[u].push_back(pii(v, w));
    add(u, v, inf, -w);
    tot += w;
  }
  DAG_longest_path(0, n - 1);
  int s = n, t = n + 1;
  V = n + 2;
  add(n - 1, 0, inf, len[0]);
  for (int i = 0; i < n; i++) {
    if (vin[i] > vout[i]) {
      add(s, i, vin[i] - vout[i], 0);
      vout[s] += vin[i] - vout[i];
    } else if (vout[i] > vin[i]) {
      add(i, t, vout[i] - vin[i], 0);
    }
  }
  cout << min_cost_flow(s, t, vout[s]) - tot << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define all(x) (x).begin(), (x).end()
#define size(x) ((int)(x).size())
#define FIRST first
#define SECOND second
#define FRONT front
#define PUSH_BACK push_back
#define MAKE_PAIR make_pair
#define EMPTY empty
#define PRIORITY_QUEUE priority_queue
using namespace std;
typedef long long LL;
typedef unsigned int uii;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
// head

const int maxn = 123;
int vin[maxn], vout[maxn];
const int inf = 1e8;
int len[maxn];
struct edge {
  int v, r, w, c;
};
std::vector<edge> G[maxn];
int h[maxn], dist[maxn];
int pv[maxn], pe[maxn];
int V;
std::vector<pii> d[maxn];
int DAG_longest_path(int u, int t) {
  if (u == t || len[u])
    return len[u];
  for (auto e : d[u]) {
    len[u] = max(len[u], e.second + DAG_longest_path(e.first, t));
  }
  return len[u];
}

void add(int u, int v, int w, int cost) {
  G[u].push_back((edge){v, size(G[v]), w, cost});
  G[v].push_back((edge){u, size(G[u]) - 1, 0, -cost});
}

int min_cost_flow(int s, int t, int flow) {
  int res = 0;
  fill(h, h + V, 0);
  while (flow > 0) {
    fill(dist, dist + V, inf);
    dist[s] = 0;
    priority_queue<pii, std::vector<pii>, greater<pii>> q;
    q.push(pii(0, s));
    while (!q.empty()) {
      pii x = q.top();
      q.pop();
      int u = x.second;
      if (dist[u] < x.first)
        continue;
      for (int i = 0; i < size(G[u]); i++) {
        edge &e = G[u][i];
        int k = h[u] + dist[u] + e.c - h[e.v];
        if (k < dist[e.v] && e.w > 0) {
          dist[e.v] = k;
          q.push(pii(k, e.v));
          pv[e.v] = u;
          pe[e.v] = i;
        }
      }
    }
    if (dist[t] == inf) {
      return -1; // 不能再增广
    }
    for (int i = 0; i < V; i++) {
      h[i] += dist[i];
    }
    int tf = flow;
    for (int v = t; v != s; v = pv[v]) {
      tf = min(tf, G[pv[v]][pe[v]].w);
    }
    if (tf) {
      for (int v = t; v != s; v = pv[v]) {
        edge &e = G[pv[v]][pe[v]];
        e.w -= tf;
        G[v][e.r].w += tf;
      }
      res += tf * h[t];
      flow -= tf;
    }
  }
  return res;
}

int main(int argc, char const *argv[]) {
#ifndef ONLINE_JUDGE
  // freopen("in.txt", "r", stdin);
  //  freopen("out.txt", "w", stdout);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  int tot = 0;
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    vin[v]++, vout[u]++;
    d[u].push_back(pii(v, w));
    add(u, v, inf, -w);
    tot += w;
  }
  DAG_longest_path(0, n - 1);
  int s = n, t = n + 1;
  V = n + 2;
  add(n - 1, 0, inf, len[0]);
  for (int i = 0; i < n; i++) {
    if (vin[i] > vout[i]) {
      add(s, i, vin[i] - vout[i], 0);
      vout[s] += vin[i] - vout[i];
    } else if (vout[i] > vin[i]) {
      add(i, t, vout[i] - vin[i], 0);
    }
  }
  cout << min_cost_flow(s, t, vout[s]) - tot << endl;
  return 0;
}