F - Add One Edge 2 Editorial by evima

別解

数えたいものは、頂点のペア \((u, v)\)(ただし \(u < v\))であって次の条件を満たすものの個数です。

  • 頂点 \(u, v\) の次数はともに \(2\)
  • 頂点 \(u, v\) を結ぶ単純パス上の頂点(\(u, v\) を除く)の次数はすべて \(3\)

これは、次数 \(3\) の頂点すべてからなる頂点集合が誘導する部分グラフの連結成分を列挙すれば求められます。各連結成分について、それと隣接する次数 \(2\) の頂点の個数を \(c\) とすると、その連結成分から \(c(c-1)/2\) 個のペアが得られます。

実装例 (Python):

from atcoder.dsu import DSU

N = int(input())
u, v = [0] * (N - 1), [0] * (N - 1)
deg = [0] * N
for i in range(N - 1):
    u[i], v[i] = map(int, input().split())
    u[i], v[i] = u[i] - 1, v[i] - 1
    deg[u[i]] += 1
    deg[v[i]] += 1

d = DSU(N)
c2 = [0] * N
for i in range(N - 1):
    if deg[u[i]] == deg[v[i]] == 3:
        d.merge(u[i], v[i])
    elif deg[u[i]] == 3 and deg[v[i]] == 2:
        c2[u[i]] += 1
    elif deg[u[i]] == 2 and deg[v[i]] == 3:
        c2[v[i]] += 1

ans = 0
for g in d.groups():
    c = 0
    for v in g:
        c += c2[v]
    ans += c * (c - 1) // 2
print(ans)

posted:
last update: