競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 292E

ABC292E

辺の取り方は \(O(N^2)\) . しかし,辺の追加がやっかいで,シュミレーションするとRE,TLEになりやすい.
最終的なグラフの性質に注目する. 頂点 \(x\) に対して, \(x\)から追加すべき点は何かを考える. \(x\) から何度か辺を辿って辿り着ける点すべてに, \(x\) から辺が張られている. これはDFSで実装可能で,合計 \(O(N(N+M))\) . よって,頂点を全探索する方針で解けることになる.

使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"

int main() {
  ll n, m ;
  cin >> n >> m;
  vvll to(n);
  rep(i,m){
    ll a,b;
    cin >> a >> b;
    --a, --b;
    to[a].push_back(b);
  }

  vll vis(n);
  auto dfs = [&](auto dfs, ll cu, ll pa, vll &tmp) -> void {
    if(vis[cu]) return ;
    vis[cu] = true;
    tmp.push_back(cu);
    for(ll ne: to[cu]){ // if(ne != pa)
      dfs(dfs, ne, cu, tmp);
    }
  };

  vvll v(n);
  rep(i,n){
    vis = vll(n);
    dfs(dfs, i, -1, v[i]);
  }

  ll ans = 0;
  rep(i,n){
    ans += v[i].size() - to[i].size() - 1; // i自身は除く
  }
  cout << ans << endl;
 

  return 0;
}