1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #include <iostream> #include <cstdio> #include <limits> #include <random> #include <ctime> #include <algorithm> #include <unordered_map> #define maxn 100010 #define ull unsigned long long using namespace std;
default_random_engine r(time(0) + 20011203); uniform_int_distribution<ull> R(1, numeric_limits<ull>::max()); ull B = R(r); ull I = R(r);
int n, m;
unordered_map<ull, int> mp;
struct Edge { int to, next; } e[maxn * 2]; int c1, head[maxn], du[maxn]; inline void add_edge(int u, int v) { e[c1].to = v; e[c1].next = head[u]; head[u] = c1++; }
ull f[maxn], g[maxn]; int sz[maxn]; void dfs(int u, int fa) { sz[u] = 1; f[u] = I; for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if (v == fa) continue; dfs(v, u); f[u] ^= f[v] * B + sz[v]; sz[u] += sz[v]; } }
void Dfs(int u, int fa) { for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if (v == fa) continue; g[v] = f[v] ^ (g[u] ^ f[v] * B + sz[v]) * B + n - sz[v]; Dfs(v, u); } }
int ans[maxn]; int main() { fill(head, head + maxn, -1); ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> n; for (int i = 1; i < n; ++i) { int x, y; cin >> x >> y; add_edge(x, y); add_edge(y, x); } dfs(1, 0); g[1] = f[1]; Dfs(1, 0); for (int i = 1; i <= n; ++i) mp[g[i]] = 1; fill(head, head + maxn, -1); c1 = 0; ++n; for (int i = 1; i < n; ++i) { int x, y; cin >> x >> y; add_edge(x, y); add_edge(y, x); ++du[x]; ++du[y]; } dfs(1, 0); g[1] = f[1]; Dfs(1, 0); for (int u = 1; u <= n; ++u) { if (du[u] != 1) continue; int v = e[head[u]].to; ull w = g[v] ^ I * B + 1; if (mp.find(w) != mp.end()) return cout << u << "\n", 0; } return 0; }
|