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

#include <algorithm>
#include <array>
#include <climits>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <queue>
#include <string>
#include <vector>
using namespace std;

const double pi = 4 * atan(1.0);
using cMatrixRepEdges = std::vector<std::vector<int>>;
pair<vector<int>, int>
solve_by_EdmondsKarp_helper(const cMatrixRepEdges &ResidualNetwork, int source,
                            int sink) {
  if (ResidualNetwork.empty())
    return make_pair(vector<int>(), 0);

  vector<bool> IsVisit(ResidualNetwork.size(), false);
  vector<int> Parents(ResidualNetwork.size(), -1);
  queue<pair<int, int>> Q;
  Q.push(make_pair(source, INT_MAX));
  IsVisit[source] = true;

  int ans = 0;
  while (!Q.empty()) {
    auto now = Q.front();
    Q.pop();
    if (now.first == sink) {
      ans = now.second;
      break;
    }

    for (int i = 0; i < ResidualNetwork.size(); ++i) {
      if (ResidualNetwork[now.first][i] > 0 && !IsVisit[i]) {
        IsVisit[i] = true;
        Parents[i] = now.first;
        Q.push(make_pair(i, min(now.second, ResidualNetwork[now.first][i])));
      }
    }
  }

  return make_pair(Parents, ans);
}
cMatrixRepEdges solve_by_EdmondsKarp(const cMatrixRepEdges &FlowNetwork,
                                     int source, int sink) {
  if (FlowNetwork.empty() || source < 0 || FlowNetwork.size() <= source ||
      sink < 0 || FlowNetwork.size() <= sink)
    return cMatrixRepEdges();

  cMatrixRepEdges ResidualNetwork = FlowNetwork;
  cMatrixRepEdges AnsFlow(FlowNetwork.size(),
                          vector<int>(FlowNetwork.size(), 0));

  while (1) {
    auto ans = solve_by_EdmondsKarp_helper(ResidualNetwork, source, sink);
    // source??????sink???????????????????????????????????£???
    if (ans.first[sink] < 0)
      break;

    int to = sink;
    int from = ans.first[sink];
    while (to != source) {
      if (FlowNetwork[from][to] > 0) {
        AnsFlow[from][to] += ans.second;
        ResidualNetwork[from][to] = FlowNetwork[from][to] - AnsFlow[from][to];
        ResidualNetwork[to][from] = AnsFlow[from][to];
      } else {
        AnsFlow[to][from] -= ans.second;
        ResidualNetwork[to][from] = FlowNetwork[to][from] - AnsFlow[to][from];
        ResidualNetwork[from][to] = AnsFlow[to][from];
      }

      to = from;
      from = ans.first[from];
    }
  }

  return AnsFlow;
}

int main() {
  int N, M;
  cin >> N >> M;
  cMatrixRepEdges Edges(N, vector<int>(N, 0));
  for (int i = 0; i < M; ++i) {
    int u, v, w;
    cin >> u >> v >> w;

    Edges[u][v] = w;
    // Edges[u].push_back(v);
  }

  auto ans = solve_by_EdmondsKarp(Edges, 0, N - 1);

  int flow = 0;
  for (const auto &val : ans[0]) {
    flow += val;
  }

  for (int i = 0; i < N; ++i) {
    flow -= ans[i][0];
  }

  cout << flow << endl;

  // system("pause");
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <climits>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <queue>
#include <string>
#include <vector>
using namespace std;

const double pi = 4 * atan(1.0);
using cMatrixRepEdges = std::vector<std::vector<int>>;
pair<vector<int>, int>
solve_by_EdmondsKarp_helper(const cMatrixRepEdges &ResidualNetwork, int source,
                            int sink) {
  if (ResidualNetwork.empty())
    return make_pair(vector<int>(), 0);

  vector<bool> IsVisit(ResidualNetwork.size(), false);
  vector<int> Parents(ResidualNetwork.size(), -1);
  queue<pair<int, int>> Q;
  Q.push(make_pair(source, INT_MAX));
  IsVisit[source] = true;

  int ans = 0;
  while (!Q.empty()) {
    auto now = Q.front();
    Q.pop();
    if (now.first == sink) {
      ans = now.second;
      break;
    }

    for (int i = 0; i < ResidualNetwork.size(); ++i) {
      if (ResidualNetwork[now.first][i] > 0 && !IsVisit[i]) {
        IsVisit[i] = true;
        Parents[i] = now.first;
        Q.push(make_pair(i, min(now.second, ResidualNetwork[now.first][i])));
      }
    }
  }

  return make_pair(Parents, ans);
}
cMatrixRepEdges solve_by_EdmondsKarp(const cMatrixRepEdges &FlowNetwork,
                                     int source, int sink) {
  if (FlowNetwork.empty() || source < 0 || FlowNetwork.size() <= source ||
      sink < 0 || FlowNetwork.size() <= sink)
    return cMatrixRepEdges();

  cMatrixRepEdges ResidualNetwork = FlowNetwork;
  cMatrixRepEdges AnsFlow(FlowNetwork.size(),
                          vector<int>(FlowNetwork.size(), 0));

  while (1) {
    auto ans = solve_by_EdmondsKarp_helper(ResidualNetwork, source, sink);
    // source??????sink???????????????????????????????????£???
    if (ans.first[sink] < 0)
      break;

    int to = sink;
    int from = ans.first[sink];
    while (to != source) {
      if (FlowNetwork[from][to] > 0) {
        AnsFlow[from][to] += ans.second;
      } else {
        AnsFlow[to][from] -= ans.second;
        swap(from, to);
      }
      ResidualNetwork[from][to] = FlowNetwork[from][to] - AnsFlow[from][to];
      ResidualNetwork[to][from] = AnsFlow[from][to];

      to = from;
      from = ans.first[from];
    }
  }

  return AnsFlow;
}

int main() {
  int N, M;
  cin >> N >> M;
  cMatrixRepEdges Edges(N, vector<int>(N, 0));
  for (int i = 0; i < M; ++i) {
    int u, v, w;
    cin >> u >> v >> w;

    Edges[u][v] = w;
    // Edges[u].push_back(v);
  }

  auto ans = solve_by_EdmondsKarp(Edges, 0, N - 1);

  int flow = 0;
  for (const auto &val : ans[0]) {
    flow += val;
  }

  for (int i = 0; i < N; ++i) {
    flow -= ans[i][0];
  }

  cout << flow << endl;

  // system("pause");
  return 0;
}