先 DFS 求图 2 连通块,然后 DFS 求图 1 连通块(碰到边连接图 2 两个不同连通块时删除这条边并且认为不连通),然后图 1 每多一个连通块就要多加一条边
#include <iostream>
#include <vector>
using namespace std;
int n;
int m1;
int m2;
vector<vector<int>> graph1;
vector<vector<int>> graph2;
vector<int> ltk;
int res;
vector<bool> vis;
void Dfs2(int x) {
ltk[x] = res;
for (const auto& y : graph2[x]) {
if (!ltk[y]) {
Dfs2(y);
}
}
}
void Dfs1(int x) {
vis[x] = true;
for (const auto& y : graph1[x]) {
if (ltk[x] != ltk[y]) {
res++;
continue;
}
if (!vis[y]) {
Dfs1(y);
}
}
}
void Solve() {
cin >> n >> m1 >> m2;
graph1.assign(n + 1, {});
graph2.assign(n + 1, {});
ltk.assign(n + 1, {});
vis.assign(n + 1, false);
while (m1--) {
int u, v;
cin >> u >> v;
graph1[u].push_back(v);
graph1[v].push_back(u);
}
while (m2--) {
int u, v;
cin >> u >> v;
graph2[u].push_back(v);
graph2[v].push_back(u);
}
res = 0;
for (int i = 1; i <= n; i++) {
if (!ltk[i]) {
res++;
Dfs2(i);
}
}
res *= -2;
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
res += 2;
Dfs1(i);
}
}
cout << res / 2 << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
Solve();
}
}
// 64 位输出请用 printf("%lld")

京公网安备 11010502036488号