Official

C - Graph Isomorphism Editorial by KoD


整数 \(X_{i, j}\) を、高橋君のおもちゃにおいてボール \(i, j\) を結ぶひもが存在するなら \(1\)、そうでないなら \(0\) と定めます。
同様に、整数 \(Y_{i, j}\) を、青木君のおもちゃにおいてボール \(i, j\) を結ぶひもが存在するなら \(1\)、そうでないなら \(0\) と定めます。

\((1, 2, \dots, N)\) を並べ替えて得られる順列 \(P\) を全探索することを考えます。\(P\) が条件をみたすことは、次が成り立つことと同値です。

  • 任意の \(1 \leq i \leq N, 1 \leq j \leq N\) に対し \(X_{i, j} = Y_{P_i, P_j}\)

これが成り立つかどうかは \(O(N^2)\) で判定することができます。\(P\) としては \(N!\) 通りあるので、全体の計算量は \(O(N^2 \times N!)\) となり、実行時間制限に間に合います。

順列の全列挙は、C++ であれば std::next_permutations、Python であれば itertools.permutations を使うのがよいでしょう。

実装例 (C++) :

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    vector x(n, vector<bool>(n)), y(n, vector<bool>(n));
    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a -= 1, b -= 1;
        x[a][b] = x[b][a] = true;
    }
    for (int i = 0; i < m; ++i) {
        int c, d;
        cin >> c >> d;
        c -= 1, d -= 1;
        y[c][d] = y[d][c] = true;
    }
    vector<int> p(n);
    iota(begin(p), end(p), 0);
    int ans = 0;
    do {
        bool ok = true;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (x[i][j] != y[p[i]][p[j]]) {
                    ok = false;
                }
            }
        }
        if (ok) {
            cout << "Yes\n";
            return 0;
        }
    } while (next_permutation(begin(p), end(p)));
    cout << "No\n";
}

実装例 (Python) :

import itertools

n, m = map(int, input().split())
a = [[False] * n for _ in range(n)]
b = [[False] * n for _ in range(n)]

for _ in range(m):
  u, v = map(int, input().split())
  u -= 1
  v -= 1
  a[u][v] = a[v][u] = True
  
for _ in range(m):
  u, v = map(int, input().split())
  u -= 1
  v -= 1
  b[u][v] = b[v][u] = True
  
ans = False
for p in itertools.permutations(range(n)):
  ok = True
  for i in range(n):
    for j in range(n):
      if a[i][j] != b[p[i]][p[j]]:
      	ok = False
  if ok:
    ans = True
print("Yes" if ans else "No")

posted:
last update: