#题意:给定一个数组p,其中p[i]为i的父节点,求得不重合,且覆盖所有结点的最小路径数,并分别输出路径,从父节点到子节点的顺序输出路径。
#思路:首先用数组值来记录每个结点的父节点,一棵无环的树且只有一个父节点,若出现x个父节点,则一定在路径中存在着x个父节点,所以最后最少的路径数用最低结点数计算为总结点数除去父节点的子节点数为(n-x);
#include<bits/stdc++.h>
using namespace std;
int a[200015],ans[200015];
bool m[200010];
map<int ,bool>mp;
int main(){
int t;cin>>t;
while(t--){
int n;cin>>n;
mp.clear();
memset(m,0,sizeof(m));
for(int i=1;i<=n;i++){
cin>>a[i];
if(!mp.count(a[i])) mp[a[i]]=1;//记录父节点
}
if(n==1) { cout<<1<<"\n"<<1<<"\n"<<1<<"\n"; continue;}
cout<<n-mp.size()<<endl;
int cnt=0;
for(int i=1;i<=n;i++){
int p=i;
if(!mp.count(p)){//判断是否是父节点
cnt=0;
while(!m[p]){//从下往上依次查找未走过的结点并记录路径
ans[++cnt]=p;//记录路径
m[p]=1;//标记已经走过
p=a[p];//向上查找
}
cout<<cnt<<endl;//输出路径结点个数
for(int j=cnt;j>=1;j--) cout<<ans[j]<<" ";
cout<<endl;
}
}
}
return 0;
}