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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

int main() {
  int N;
  cin >> N;
  map<string, pair<int, int>> ing;

  vector<pair<int, int>> v(N);
  for (int i = 0; i < N; i++) {
    string s;
    int x;
    cin >> s >> x;
    ing[s] = {x, i};
    v[i] = {x, i};
  }

  sort(v.begin(), v.end());

  vector<vector<int>> G(N);
  int M;
  cin >> M;
  for (int i = 0; i < M; i++) {
    char c[100];
    char c_[100];
    scanf("%s %s", c, c_);
    string s_(c), t_(c_);

    int x = ing.find(s_)->second.second;
    int y = ing.find(t_)->second.second;

    G[x].push_back(y);
    G[y].push_back(x);
  }

  vector<bool> used(N, false);
  long long ans = 0;

  function<long long(int)> dfs = [&](int pos) -> long long {
    if (used[pos])
      return 0;
    used[pos] = true;
    long long ret = 0;
    for (int i = 0; i < G[pos].size(); i++) {
      ret += dfs(G[pos][i]);
    }
    return ret + 1;
  };

  for (int i = 0; i < N; i++) {
    ans += v[i].first * dfs(v[i].second);
  }
  cout << ans << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define INF 1e8

typedef struct {
  int to;
  int cap;
  int cost;
  int rev;
} edge;

// min cost : s->t (flow:f)
int min_cost_flow(vector<vector<edge>> &G, int s, int t, int f) {
  int cost = 0;
  vector<int> prev_v(G.size(), -1);
  vector<int> prev_e(G.size(), -1);

  while (f > 0) {
    // min distance(cost based) search with Belman-Ford
    vector<int> dist(G.size(), INF);
    dist[s] = 0;
    prev_v[s] = s;
    bool update = true;
    while (update) {
      update = false;
      for (int i = 0; i < G.size(); i++) {
        if (dist[i] >= INF)
          continue;

        vector<edge> &e = G[i];
        for (int j = 0; j < e.size(); j++) {
          if (dist[e[j].to] > dist[i] + e[j].cost && e[j].cap > 0) {
            dist[e[j].to] = dist[i] + e[j].cost;
            update = true;
            prev_v[e[j].to] = i;
            prev_e[e[j].to] = j;
          }
        }
      }
    }

    // cannot achieved to "t" return -1
    if (dist[t] >= INF)
      return -1;

    // add cost of s->t with flow=d
    int pos = t;
    int d = INF;
    while (pos != s) {
      int i = prev_v[pos];
      int j = prev_e[pos];
      pos = i;
      d = min(d, G[i][j].cap);
    }

    pos = t;
    // cout << t ;
    while (pos != s) {
      int i = prev_v[pos];
      int j = prev_e[pos];
      G[i][j].cap -= d;
      G[G[i][j].to][G[i][j].rev].cap += d;
      // cost += G[i][j].cost * d;
      pos = i;
      // cout << " <- " << pos;
    }
    // cout << endl;
    cost += d * dist[t];
    f -= d;

    // f==0 then end
  }
  return cost;
}

void add_edge(vector<vector<edge>> &G, int from, int to, int cap, int cost) {
  G[from].push_back((edge){to, cap, cost, (int)G[to].size()});
  G[to].push_back((edge){from, 0, -cost, (int)G[from].size() - 1});
}

int main() {
  int N;
  cin >> N;
  map<string, pair<int, int>> ing;
  for (int i = 0; i < N; i++) {
    string s;
    int x;
    cin >> s >> x;
    ing[s] = {x, i};
  }

  vector<vector<edge>> G(N + 2);
  int s = N + 0;
  int t = N + 1;

  for (auto itr = ing.begin(); itr != ing.end(); itr++) {
    add_edge(G, s, itr->second.second, INF, itr->second.first);
    add_edge(G, itr->second.second, t, 1, 0);
  }

  int M;
  cin >> M;
  for (int i = 0; i < M; i++) {
    char c[100];
    char c_[100];
    scanf("%s %s", c, c_);
    string s_(c), t_(c_);

    auto itr_s = ing.find(s_);
    auto itr_t = ing.find(t_);

    add_edge(G, itr_s->second.second, itr_t->second.second, INF, 0);
    add_edge(G, itr_t->second.second, itr_s->second.second, INF, 0);
  }

  long long ans = min_cost_flow(G, s, t, N);
  cout << ans << endl;
  return 0;
}