原题连接ios
题目:spa
给定一个包含n个点(编号为1~n)的无向图,初始时图中没有边。code
如今要进行m个操做,操做共有三种:ci
输入格式get
第一行输入整数n和m。string
接下来m行,每行包含一个操做指令,指令为“C a b”,“Q1 a b”或“Q2 a”中的一种。io
输出格式stream
对于每一个询问指令”Q1 a b”,若是a和b在同一个连通块中,则输出“Yes”,不然输出“No”。数据
对于每一个询问指令“Q2 a”,输出一个整数表示点a所在连通块中点的数量集合
每一个结果占一行。
数据范围
1 ≤ n, m ≤ 10^5
输入样例:
5 5 C 1 2 Q1 1 2 Q2 1 C 2 5 Q2 5
输出样例:
Yes 2 3
完整AC代码:
#include <iostream> #include <cstdio> using namespace std; const int N = 100010; int p[N], cnt[N]; int n, m; int findRoot(int x){ if(p[x] != x) p[x] = findRoot(p[x]); return p[x]; } int main(){ cin >> n >> m; for(int i = 1; i <= n; i++){ p[i] = i; cnt[i] = 1; } while(m --){ string op; int a, b; cin >> op; if(op == "C"){ scanf("%d%d", &a, &b); if(findRoot(a) != findRoot(b)){ //若是a,b不在同一集合内 cnt[findRoot(b)] += cnt[findRoot(a)]; p[findRoot(a)] = findRoot(b); } } else if (op == "Q1"){ scanf("%d%d", &a, &b); if(findRoot(a) == findRoot(b)) puts("Yes"); else puts("No"); } else{ scanf("%d", &a); printf("%d\n", cnt[findRoot(a)]); } } return 0; }