很简单的并查集裸题了,基本没啥需要额外维护的信息,题目分两步解决,
第一步:先将有关系的元素放到一个集合里面。
第二步:将所有有公共关系的元素都在一个bool数组里标记为true,之后遍历
的时候将false的元素,也就是没有公共关系的元素挨个累加(一个元素在一个桌子),
然后对于那些为true的元素,因为他们都是在一个桌子里的,因此只要判断他们的
父节点是不是自己,如果是就加一。
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 const int N = 1010; 5 bool vis[N]; 6 int fa[N]; 7 int find(int x){ 8 if(x != fa[x]) fa[x] = find(fa[x]); 9 return fa[x]; 10 } 11 int main(){ 12 int t; 13 cin >> t; 14 while(t --){ 15 int n, m, ans = 0; 16 cin >> n >> m; 17 for(int i = 1; i <= n; i ++) fa[i] = i; 18 for(int i = 1; i <= m; i ++){ 19 int a, b; 20 cin >> a >> b; 21 if(find(a) != find(b)){ 22 fa[find(a)] = find(b); 23 vis[find(a)] = true; 24 vis[a] = true; 25 } 26 } 27 for(int i = 1; i <= n; i ++){ 28 if(!vis[i]) 29 ans ++; 30 else 31 if(i == fa[i]) 32 ans ++; 33 } 34 cout << ans << endl; 35 } 36 37 return 0; 38 }