题目翻译 在战争中,所有的城市都通过公路连接起来是至关重要的。
如果一座城市被敌人占领,所有通往该城市的公路都将关闭。
我们必须立即知道是否需要修复任何其他公路来保持其他城市的连接。
给定标有所有剩余高速公路的城市地图,你应该快速说出需要修复的高速公路的数量。
例如,共有 3 座城市,由 2 条高速公路将它们连通,一条连接城市 1 和城市 2,一条连接城市 1 和城市 3。
当城市 1 被敌人占领时,我们需要在城市 2 和城市 3 之间维修一条高速公路,以保持这两座城市的连通。
输入格式 第一行包含三个整数 N, M, K,分别表示城市总数,高速公路总数,重点关注城市数量。 接下来 M 行,每行包含两个整数 a, b,表示城市 a 和城市 b 之间存在一条高速公路。所有城市编号从 1 到 N。 最后一行,包含 K 个整数,表示重点关注的城市编号。
输出格式 共 K 行,每行输出一个重点关注城市被占领时,为了保持其余城市连通性,需要维修的最少高速公路条数。
数据范围 N < 1000
输入样例 3 2 3 1 2 1 3 1 2 3
输出样例 1 0 0
题解 并查集:
解题步骤:
先求出所有剩余连通块, 假设连通块数量为 n;那么 n - 1 条边就能将 n 个点全部连接起来; #include <cstdio> #include <vector> using namespace std; const int N = 1010; int p[N]; int n, m, k; vector<int> g[N]; int find(int x) { if(p[x] != x) p[x] = find(p[x]); return p[x]; } int main() { scanf("%d%d%d", &n, &m, &k); while(m --) { int a, b; scanf("%d%d", &a, &b); g[a].push_back(b); g[b].push_back(a); } while(k --) { int x; scanf("%d", &x); for (int i = 1; i <= n; i ++) p[i] = i; int cnt = n - 1; for (int i = 1; i <= n; i ++) { if(i == x) continue; // 破坏城市 x 的出边 for (int j = 0; j < g[i].size(); j ++) { if(g[i][j] == x) continue; // 破坏城市 x 的入边 int pa = find(i), pb = find(g[i][j]); if(pa != pb) { cnt --; p[pa] = pb; } } } printf("%d\n", cnt - 1); } return 0; }