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

#include <algorithm> // other
#include <bitset>
#include <cassert> // c
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream> // io
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <vector> // container
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define ALL(c) c.begin(), c.end()
#define REP(i, n) FOR(i, 0, n)
#define REPr(i, n) FORr(i, 0, n)
#define FOR(i, l, r) for (int i = (int)(l); i < (int)(r); ++i)
#define FORr(i, l, r) for (int i = (int)(r)-1; i >= (int)(l); --i)
// #define EACH(it,o) for(auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))
#define UNIQUE(v) v.erase(unique(ALL(v)), v.end())
// debug
#define DUMP(x) cerr << #x << " = " << (x)
#define LINE() cerr << " (L" << __LINE__ << ")"

class range {
private:
  struct Iter {
    int v;
    int operator*() { return v; }
    bool operator!=(Iter &itr) { return v < itr.v; }
    void operator++() { ++v; }
  };
  Iter i, n;

public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iter &begin() { return i; }
  Iter &end() { return n; }
};

// input
template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  return is >> p.first >> p.second;
}
template <typename T1> istream &operator>>(istream &is, tuple<T1> &t) {
  return is >> get<0>(t);
}
template <typename T1, typename T2>
istream &operator>>(istream &is, tuple<T1, T2> &t) {
  return is >> get<0>(t) >> get<1>(t);
}
template <typename T1, typename T2, typename T3>
istream &operator>>(istream &is, tuple<T1, T2, T3> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t);
}
template <typename T1, typename T2, typename T3, typename T4>
istream &operator>>(istream &is, tuple<T1, T2, T3, T4> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t) >>
         get<5>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t) >>
         get<5>(t) >> get<6>(t);
}
template <typename T> istream &operator>>(istream &is, vector<T> &as) {
  for (int i : range(as.size()))
    is >> as[i];
  return is;
}

// output
template <typename T> ostream &operator<<(ostream &os, const set<T> &ss) {
  for (auto a : ss) {
    if (a != ss.begin())
      os << " ";
    os << a;
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << p.first << " " << p.second;
}
template <typename K, typename V>
ostream &operator<<(ostream &os, const map<K, V> &m) {
  bool isF = true;
  for (auto &p : m) {
    if (!isF)
      os << endl;
    os << p;
    isF = false;
  }
  return os;
}
template <typename T1> ostream &operator<<(ostream &os, const tuple<T1> &t) {
  return os << get<0>(t);
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const tuple<T1, T2> &t) {
  return os << get<0>(t) << " " << get<1>(t);
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t);
}
template <typename T1, typename T2, typename T3, typename T4>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t) << " " << get<5>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t) << " " << get<5>(t) << " "
            << get<6>(t);
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &as) {
  for (int i : range(as.size())) {
    if (i != 0)
      os << " ";
    os << as[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &as) {
  for (int i : range(as.size())) {
    if (i != 0)
      os << endl;
    os << as[i];
  }
  return os;
}

// values
template <typename T> inline T INF() { assert(false); };
template <> inline int INF<int>() { return 1 << 28; };
template <> inline ll INF<ll>() { return 1LL << 58; };
template <> inline double INF<double>() { return 1e16; };
template <> inline long double INF<long double>() { return 1e16; };

template <class T> inline T EPS() { assert(false); };
template <> inline int EPS<int>() { return 1; };
template <> inline ll EPS<ll>() { return 1LL; };
template <> inline double EPS<double>() { return 1e-8; };
template <> inline long double EPS<long double>() { return 1e-8; };

// min{2^r | n < 2^r}
template <typename T> T upper_pow2(T n) {
  T res = 1;
  while (res < n)
    res <<= 1;
  return res;
}
// max{d | 2^d  <= n}
template <typename T> T msb(T n) {
  int d = 30;
  while ((1 << d) > n)
    d--;
  return d;
}

template <typename T, typename U> T pmod(T v, U M) { return (v % M + M) % M; }

class MaximamFlow {
private:
  typedef int Flow;
  struct Edge {
    int to, rev;
    Flow icap, cap;
    bool ex;
  };
  typedef vector<vector<Edge>> Graph;

  // iter　次に調べる時の開始位置 距離
  vector<int> iter, dist;

  // sからのbfs距離の計算
  void bfs_dist(int s) {
    fill(ALL(dist), -1);
    dist[s] = 0;
    queue<int> que;
    que.push(s);
    while (!que.empty()) {
      int v = que.front();
      que.pop();
      for (Edge &e : G[v])
        if (e.cap > 0 && dist[e.to] == -1) {
          dist[e.to] = dist[v] + 1;
          que.push(e.to);
        }
    }
  }

  // 増加パス
  Flow dfs_best_path(int s, int t, Flow f) {
    if (s == t)
      return f;
    for (int &i = iter[s]; i < (int)G[s].size(); i++) {
      Edge &e = G[s][i];
      Edge &reve = G[e.to][e.rev];
      if (e.cap <= 0 || dist[s] >= dist[e.to])
        continue;
      // search
      Flow d = dfs_best_path(e.to, t, min(f, e.cap));
      if (d == 0)
        continue;
      // found
      e.cap -= d;
      reve.cap += d;

      return d;
    }
    return 0;
  }

public:
  int V;
  Graph G;
  MaximamFlow(int V) : V(V) {
    G = Graph(V);
    dist = vector<int>(V, -1);
    iter = vector<int>(V);
  }

  void add_edge(int s, int t, Flow cap) {
    int srev = G[t].size(), trev = G[s].size();
    G[s].push_back({t, srev, cap, cap, true});
    G[t].push_back({s, trev, 0, 0, false});
  }

  Flow change_cost(int S, int T, int s, int t, int c) {
    Flow flow = 0;
    for (Edge &e : G[s])
      if (e.to == t) {
        Edge &reve = G[e.to][e.rev];
        if (e.icap <= c) { // 単純に増やす
          // cerr <<"add"<<endl;
          e.cap += c - e.icap;
          e.icap = c;
        } else if (c >= e.icap - e.cap) { // 単純に減らす
          // cerr <<"del"<<endl;
          e.cap -= e.icap - c;
          e.icap = c;
        } else { // フローを戻してから減らす
          // cerr <<"del2"<<endl;
          // cerr << s+1 <<" " << t+1 <<endl;
          Flow d = e.icap - e.cap - c;

          // 出来るだけs->tを使わないフローに置き換える
          Flow revd = max_flow(s, t, d);
          max_flow(T, S, d - revd);
          assert(max_flow(s, t, d - revd) == d - revd);

          flow -= d - revd;
          // cerr << d-revd <<endl;
          // cerr << make_tuple(e.cap,e.icap,reve.cap,reve.icap)<<endl;
          e.cap = 0;
          e.icap = 0;
          reve.cap = 0;
          reve.icap = 0;
          // e.cap =0;reve.cap = 0;

          // // cerr <<"!preflow!"<<endl;
          // // REP(v,G.size())for(Edge& e2:G[v]){
          // // 	Edge &reve2 = G[e2.to][e2.rev];
          // // 	cerr << v+1 <<"->" << e2.to+1 <<" " <<e2.icap <<" " <<
          // e2.cap<<endl;
          // // }
          // // cerr <<endl;
          // // cerr << d <<endl;

          // // S <- s <- t <- T のパス
          // // cerr << make_tuple(s,S,d) <<endl;
          // Flow fs = max_flow(s,S,d);
          // Flow ft = max_flow(T,t,d);
          // Flow f = min(fs,ft);
          // // cerr <<"::f" <<f <<endl;
          // flow -= f;
          // // cerr << f <<" " << fs <<" " << ft <<endl;
          // // 流しすぎ分の除去
          // max_flow(S,s,fs-f); max_flow(t,T,ft-f);
          // // 閉路の除去
          // // s -> t -> s
          // // cerr << make_tuple(s,t,d-f)<<endl;
          // Flow floop = max_flow(s,t,d-f);

          // // cerr <<make_tuple(floop,t+1,s+1) <<endl;
          // // cerr <<"!flow!"<<endl;
          // // REP(v,G.size())for(Edge& e2:G[v]){
          // // 	Edge &reve2 = G[e2.to][e2.rev];
          // // 	cerr << v+1 <<"->" << e2.to+1 <<" " <<e2.icap <<" " <<
          // e2.cap<<endl;
          // // }
          // // cerr <<endl;

          // // s <- t d戻す
          // e.cap=tmpcap + d;reve.cap = tmprevcap - d;

          // // 減らす
          // e.cap-=e.icap - c;
          e.icap = c;
        }

        // REP(v,G.size())for(Edge& e2:G[v])if(e2.ex){
        // 	assert(e2.icap == e2.cap + G[e2.to][e2.rev].cap);
        // }
        // REP(v,G.size())for(Edge& e2:G[v])if(!e2.ex){
        // 	assert(-e2.icap == e2.cap + G[e2.to][e2.rev].cap);
        // }

        // cerr << s+1 <<" " << t+1 <<endl;
        // cerr <<"!pre:state!"<<endl;
        // REP(v,G.size())for(Edge& e2:G[v]){
        // 	Edge &reve2 = G[e2.to][e2.rev];
        // 	assert(e2.cap+reve2.cap ==e2.icap + reve2.icap);
        // 	cerr << v+1 <<"->" << e2.to+1 <<" " <<e2.icap <<" " <<
        // e2.cap<<endl;
        // }
        // cerr <<endl;

        Flow _f = max_flow(S, T); // cerr <<"_f:"<< _f <<endl;
        flow += _f;

        // cerr <<"!post:state!"<<endl;
        // REP(v,G.size())for(Edge& e2:G[v]){
        // 	Edge &reve2 = G[e2.to][e2.rev];
        // 	cerr << v+1 <<"->" << e2.to+1 <<" " <<e2.icap <<" " <<
        // e2.cap<<endl;
        // }
        // REP(v,G.size())for(Edge& e2:G[v]){
        // 	Edge &reve2 = G[e2.to][e2.rev];
        // 	cerr << v+1 <<" " << e2.to+1<<endl;
        // 	assert(e2.cap+reve2.cap ==e2.icap + reve2.icap);
        // }
        // cerr <<endl;
      }

    // cerr <<"f:"<< flow <<endl;

    return flow;
  }

  int max_flow(int s, int t, Flow Mf = INF<Flow>()) {
    if (s == t)
      return Mf;
    Flow flow = 0;
    while (Mf) {
      fill(ALL(iter), 0);
      bfs_dist(s);
      if (dist[t] == -1)
        break;
      Flow f;
      while ((f = dfs_best_path(s, t, Mf)) > 0)
        flow += f, Mf -= f;
    }
    return flow;
  }
};

class Main {
public:
  void run() {
    int N, E, Q;
    cin >> N >> E >> Q;

    MaximamFlow mf(N);
    REP(i, N) REP(j, N) if (i < j) { mf.add_edge(i, j, 0); }

    REP(e, E) {
      int f, t;
      cin >> f >> t;
      f--;
      t--;
      REP(i, mf.G[f].size()) if (mf.G[f][i].to == t) {
        mf.G[f][i].cap++;
        mf.G[f][i].icap++;
      }
      REP(i, mf.G[t].size()) if (mf.G[t][i].to == f) {
        mf.G[t][i].cap++;
        mf.G[t][i].icap++;
      }
    }
    ll flow = mf.max_flow(0, N - 1);

    REP(q, Q) {
      int t, a, b;
      cin >> t >> a >> b;
      a--;
      b--;

      // cerr <<"q:"<< make_tuple(t,a+1,b+1) <<endl;
      if (t == 1) {
        flow += mf.change_cost(0, N - 1, a, b, 1);
        flow += mf.change_cost(0, N - 1, b, a, 1);
        cout << flow << endl;
      } else {
        flow += mf.change_cost(0, N - 1, a, b, 0);
        flow += mf.change_cost(0, N - 1, b, a, 0);
        cout << flow << endl;
      }
    }
  }
};

int main() {
  cout << fixed << setprecision(20);
  cin.tie(0);
  ios::sync_with_stdio(false);
  Main().run();
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm> // other
#include <bitset>
#include <cassert> // c
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream> // io
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <vector> // container
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define ALL(c) c.begin(), c.end()
#define REP(i, n) FOR(i, 0, n)
#define REPr(i, n) FORr(i, 0, n)
#define FOR(i, l, r) for (int i = (int)(l); i < (int)(r); ++i)
#define FORr(i, l, r) for (int i = (int)(r)-1; i >= (int)(l); --i)
// #define EACH(it,o) for(auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))
#define UNIQUE(v) v.erase(unique(ALL(v)), v.end())
// debug
#define DUMP(x) cerr << #x << " = " << (x)
#define LINE() cerr << " (L" << __LINE__ << ")"

class range {
private:
  struct Iter {
    int v;
    int operator*() { return v; }
    bool operator!=(Iter &itr) { return v < itr.v; }
    void operator++() { ++v; }
  };
  Iter i, n;

public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iter &begin() { return i; }
  Iter &end() { return n; }
};

// input
template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  return is >> p.first >> p.second;
}
template <typename T1> istream &operator>>(istream &is, tuple<T1> &t) {
  return is >> get<0>(t);
}
template <typename T1, typename T2>
istream &operator>>(istream &is, tuple<T1, T2> &t) {
  return is >> get<0>(t) >> get<1>(t);
}
template <typename T1, typename T2, typename T3>
istream &operator>>(istream &is, tuple<T1, T2, T3> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t);
}
template <typename T1, typename T2, typename T3, typename T4>
istream &operator>>(istream &is, tuple<T1, T2, T3, T4> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t) >>
         get<5>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t) >>
         get<5>(t) >> get<6>(t);
}
template <typename T> istream &operator>>(istream &is, vector<T> &as) {
  for (int i : range(as.size()))
    is >> as[i];
  return is;
}

// output
template <typename T> ostream &operator<<(ostream &os, const set<T> &ss) {
  for (auto a : ss) {
    if (a != ss.begin())
      os << " ";
    os << a;
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << p.first << " " << p.second;
}
template <typename K, typename V>
ostream &operator<<(ostream &os, const map<K, V> &m) {
  bool isF = true;
  for (auto &p : m) {
    if (!isF)
      os << endl;
    os << p;
    isF = false;
  }
  return os;
}
template <typename T1> ostream &operator<<(ostream &os, const tuple<T1> &t) {
  return os << get<0>(t);
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const tuple<T1, T2> &t) {
  return os << get<0>(t) << " " << get<1>(t);
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t);
}
template <typename T1, typename T2, typename T3, typename T4>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t) << " " << get<5>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t) << " " << get<5>(t) << " "
            << get<6>(t);
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &as) {
  for (int i : range(as.size())) {
    if (i != 0)
      os << " ";
    os << as[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &as) {
  for (int i : range(as.size())) {
    if (i != 0)
      os << endl;
    os << as[i];
  }
  return os;
}

// values
template <typename T> inline T INF() { assert(false); };
template <> inline int INF<int>() { return 1 << 28; };
template <> inline ll INF<ll>() { return 1LL << 58; };
template <> inline double INF<double>() { return 1e16; };
template <> inline long double INF<long double>() { return 1e16; };

template <class T> inline T EPS() { assert(false); };
template <> inline int EPS<int>() { return 1; };
template <> inline ll EPS<ll>() { return 1LL; };
template <> inline double EPS<double>() { return 1e-8; };
template <> inline long double EPS<long double>() { return 1e-8; };

// min{2^r | n < 2^r}
template <typename T> T upper_pow2(T n) {
  T res = 1;
  while (res < n)
    res <<= 1;
  return res;
}
// max{d | 2^d  <= n}
template <typename T> T msb(T n) {
  int d = 30;
  while ((1 << d) > n)
    d--;
  return d;
}

template <typename T, typename U> T pmod(T v, U M) { return (v % M + M) % M; }

class MaximamFlow {
private:
  typedef int Flow;
  struct Edge {
    int to, rev;
    Flow icap, cap;
    bool ex;
  };
  typedef vector<vector<Edge>> Graph;

  // iter　次に調べる時の開始位置 距離
  vector<int> iter, dist;

  // sからのbfs距離の計算
  void bfs_dist(int s) {
    fill(ALL(dist), -1);
    dist[s] = 0;
    queue<int> que;
    que.push(s);
    while (!que.empty()) {
      int v = que.front();
      que.pop();
      for (Edge &e : G[v])
        if (e.cap > 0 && dist[e.to] == -1) {
          dist[e.to] = dist[v] + 1;
          que.push(e.to);
        }
    }
  }

  // 増加パス
  Flow dfs_best_path(int s, int t, Flow f) {
    if (s == t)
      return f;
    for (int &i = iter[s]; i < (int)G[s].size(); i++) {
      Edge &e = G[s][i];
      Edge &reve = G[e.to][e.rev];
      if (e.cap <= 0 || dist[s] >= dist[e.to])
        continue;
      // search
      Flow d = dfs_best_path(e.to, t, min(f, e.cap));
      if (d == 0)
        continue;
      // found
      e.cap -= d;
      reve.cap += d;

      return d;
    }
    return 0;
  }

public:
  int V;
  Graph G;
  MaximamFlow(int V) : V(V) {
    G = Graph(V);
    dist = vector<int>(V, -1);
    iter = vector<int>(V);
  }

  void add_edge(int s, int t, Flow cap) {
    int srev = G[t].size(), trev = G[s].size();
    G[s].push_back({t, srev, cap, cap, true});
    G[t].push_back({s, trev, 0, 0, false});
  }

  Flow change_cost(int S, int T, int s, int t, int c) {
    Flow flow = 0;
    for (Edge &e : G[s])
      if (e.to == t) {
        Edge &reve = G[e.to][e.rev];
        if (e.icap <= c) { // 単純に増やす
          // cerr <<"add"<<endl;
          e.cap += c - e.icap;
          e.icap = c;
        } else if (c >= e.icap - e.cap) { // 単純に減らす
          // cerr <<"del"<<endl;
          e.cap -= e.icap - c;
          e.icap = c;
        } else { // フローを戻してから減らす
          // cerr <<"del2"<<endl;
          // cerr << s+1 <<" " << t+1 <<endl;
          Flow d = e.icap - e.cap - c;

          // 出来るだけs->tを使わないフローに置き換える
          Flow revd = max_flow(s, t, d);
          max_flow(T, S, d - revd);
          assert(max_flow(s, t, d - revd) == d - revd);
          flow -= d - revd;
          // cerr << d-revd <<endl;
          // cerr << make_tuple(e.cap,e.icap,reve.cap,reve.icap)<<endl;
          e.cap = 0;
          e.icap = 0;
          reve.cap = 0;
          reve.icap = 0;
          // e.cap =0;reve.cap = 0;

          // // cerr <<"!preflow!"<<endl;
          // // REP(v,G.size())for(Edge& e2:G[v]){
          // // 	Edge &reve2 = G[e2.to][e2.rev];
          // // 	cerr << v+1 <<"->" << e2.to+1 <<" " <<e2.icap <<" " <<
          // e2.cap<<endl;
          // // }
          // // cerr <<endl;
          // // cerr << d <<endl;

          // // S <- s <- t <- T のパス
          // // cerr << make_tuple(s,S,d) <<endl;
          // Flow fs = max_flow(s,S,d);
          // Flow ft = max_flow(T,t,d);
          // Flow f = min(fs,ft);
          // // cerr <<"::f" <<f <<endl;
          // flow -= f;
          // // cerr << f <<" " << fs <<" " << ft <<endl;
          // // 流しすぎ分の除去
          // max_flow(S,s,fs-f); max_flow(t,T,ft-f);
          // // 閉路の除去
          // // s -> t -> s
          // // cerr << make_tuple(s,t,d-f)<<endl;
          // Flow floop = max_flow(s,t,d-f);

          // // cerr <<make_tuple(floop,t+1,s+1) <<endl;
          // // cerr <<"!flow!"<<endl;
          // // REP(v,G.size())for(Edge& e2:G[v]){
          // // 	Edge &reve2 = G[e2.to][e2.rev];
          // // 	cerr << v+1 <<"->" << e2.to+1 <<" " <<e2.icap <<" " <<
          // e2.cap<<endl;
          // // }
          // // cerr <<endl;

          // // s <- t d戻す
          // e.cap=tmpcap + d;reve.cap = tmprevcap - d;

          // // 減らす
          // e.cap-=e.icap - c;
          e.icap = c;
        }

        // REP(v,G.size())for(Edge& e2:G[v])if(e2.ex){
        // 	assert(e2.icap == e2.cap + G[e2.to][e2.rev].cap);
        // }
        // REP(v,G.size())for(Edge& e2:G[v])if(!e2.ex){
        // 	assert(-e2.icap == e2.cap + G[e2.to][e2.rev].cap);
        // }

        // cerr << s+1 <<" " << t+1 <<endl;
        // cerr <<"!pre:state!"<<endl;
        // REP(v,G.size())for(Edge& e2:G[v]){
        // 	Edge &reve2 = G[e2.to][e2.rev];
        // 	assert(e2.cap+reve2.cap ==e2.icap + reve2.icap);
        // 	cerr << v+1 <<"->" << e2.to+1 <<" " <<e2.icap <<" " <<
        // e2.cap<<endl;
        // }
        // cerr <<endl;

        Flow _f = max_flow(S, T); // cerr <<"_f:"<< _f <<endl;
        flow += _f;

        // cerr <<"!post:state!"<<endl;
        // REP(v,G.size())for(Edge& e2:G[v]){
        // 	Edge &reve2 = G[e2.to][e2.rev];
        // 	cerr << v+1 <<"->" << e2.to+1 <<" " <<e2.icap <<" " <<
        // e2.cap<<endl;
        // }
        // REP(v,G.size())for(Edge& e2:G[v]){
        // 	Edge &reve2 = G[e2.to][e2.rev];
        // 	cerr << v+1 <<" " << e2.to+1<<endl;
        // 	assert(e2.cap+reve2.cap ==e2.icap + reve2.icap);
        // }
        // cerr <<endl;
      }

    // cerr <<"f:"<< flow <<endl;

    return flow;
  }

  int max_flow(int s, int t, Flow Mf = INF<Flow>()) {
    if (s == t)
      return Mf;
    Flow flow = 0;
    while (true) {
      fill(ALL(iter), 0);
      bfs_dist(s);
      if (Mf == 0 || dist[t] == -1)
        return flow; // 限界
      Flow f;
      while ((f = dfs_best_path(s, t, Mf)) > 0)
        flow += f, Mf -= f;
    }
    return -1;
  }
};

class Main {
public:
  void run() {
    int N, E, Q;
    cin >> N >> E >> Q;

    MaximamFlow mf(N);
    REP(i, N) REP(j, N) if (i < j) { mf.add_edge(i, j, 0); }

    ll flow = 0;
    REP(e, E) {
      int f, t;
      cin >> f >> t;
      f--;
      t--;
      flow += mf.change_cost(0, N - 1, f, t, 1);
      flow += mf.change_cost(0, N - 1, t, f, 1);
    }
    // cerr << flow <<endl;
    REP(q, Q) {
      int t, a, b;
      cin >> t >> a >> b;
      a--;
      b--;

      // cerr <<"q:"<< make_tuple(t,a+1,b+1) <<endl;
      if (t == 1) {
        flow += mf.change_cost(0, N - 1, a, b, 1);
        flow += mf.change_cost(0, N - 1, b, a, 1);
        cout << flow << endl;
      } else {
        flow += mf.change_cost(0, N - 1, a, b, 0);
        flow += mf.change_cost(0, N - 1, b, a, 0);
        cout << flow << endl;
      }
    }
  }
};

int main() {
  cout << fixed << setprecision(20);
  cin.tie(0);
  ios::sync_with_stdio(false);
  Main().run();
  return 0;
}