#include<iostream>#include<vector>#include<cstring>#include<algorithm>#include<queue>usingnamespace std;constint maxn =300;int father[maxn];//存储父节点int isRoot[maxn];//存储以这个元素为根节点时集合的元素个数voidinit(int n){for(int i =0; i <= n; i++){
father[i]= i;
isRoot[i]=1;}}intfindFather(int a){int x = a;//x最终会是根节点元素//先找到根节点while(father[x]!= x) x = father[x];//反向把经过节点的父节点直接变为根节点,压缩路径while(father[a]!= a){int b = a;
a = father[a];
father[b]= x;}return a;}//合并两个集合voidmyunion(int a,int b){int af, bf;
af =findFather(a);
bf =findFather(b);//将一个集合的根节点指向另一个集合的根节点if(af != bf) father[bf]= af;}intmain(){int n, m, a, b;scanf("%d%d",&n,&m);init(n);for(int i =0; i < m; i++){scanf("%d%d",&a,&b);myunion(a, b);}for(int i =1; i <= n; i ++){//如果当前节点所在集合的根节点不是自身if(father[i]!= i){
isRoot[father[i]]++;
isRoot[i]--;}}for(int i =1; i <= n; i ++)printf("%d ", isRoot[i]);for(int i =1; i <= n; i ++)printf("%d ", father[i]);system("pause");return0;}