競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 226E

ABC224E

連結成分毎に独立して解ける. 連結成分毎の答えを掛ける.
出ている辺と頂点が1:1対応する必要があるので, 辺の本数と頂点の個数が等しい必要がある.
逆にこのとき,連結成分は functional graph となり, サイクルが一つだけ存在する. そのサイクルに対して向きが 2通りある.
もし辺と頂点の個数が異なる場合は 0通り.

実装
握手の補題より,(頂点の個数)*2 = (辺の本数) であるかを判定する. これは DFS で可能.

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

pll operator + (pll a, pll b){
  return {a.first+b.first, a.second + b.second};
}

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);
    to[b].push_back(a);
  }

  vll vis(n);
  auto dfs = [&](auto f, ll cu, ll pa, pll p) -> pll {
    if(vis[cu]){
      return p;
    }
    vis[cu] = true;

    p.first++;
    p.second += to[cu].size();

    for(auto ne: to[cu]) {
      p = f(f, ne, cu, p);
    }

    return p;
  };



  mint ans = 1;
  rep(i,n) if(!vis[i]){
    pll pa = dfs(dfs, i, -1, pll(0,0));
    if(2*pa.first == pa.second) ans *= mint(2);
    else ans *= mint(0);
  }
  cout << ans.val() << endl;


  return 0;
}