【发布时间】:2020-02-08 07:05:26
【问题描述】:
有 n 个孩子,每个孩子都在读一本独特的书。在任何一天结束时,第 i 个孩子会将他的书交给第 pi 个孩子(如果 i=pi,孩子会将他的书交给自己)。保证 pi 的所有值都是从 1 到 n 的不同整数(即 p 是一个排列)。序列 p 每天都不会改变,它是固定的。
例如,如果 n=6 和 p=[4,6,1,3,5,2],那么在第一天结束时,第 1 个孩子的书将属于第 4 个孩子,第 2 个孩子将属于第 6 个孩子,依此类推。在第二天结束时,第 1 孩子的书将属于第 3 孩子,第 2 孩子将属于第 2 孩子,依此类推。
你的任务是确定从 1 到 n 的每一个 i,第 i 个孩子的书第一次归还给他的天数。
考虑以下示例:p=[5,1,2,4,3]。第一个孩子的书将传递给以下孩子:
在第 1 天之后,它将属于第 5 个孩子, 第二天之后它会属于第三个孩子, 第 3 天之后,它将属于第 2 个孩子, 第 4 天之后,它将属于第 1 个孩子。 所以第四天之后,第一个孩子的书就会归还给它的主人。老四的书会在整整一天后第一次回到他的身边。
你必须回答 q 个独立的查询
使用的方法
不相交集
如果 1 给 4 则找到 1 和 4 的父级。如果父级不同,则执行 1 和 4 的联合,否则移动到下一对
最后 ans 是它所属集合的大小
例如-
1
6
4 6 2 1 5 3
//在findparent中通过引用传递p时给出正确答案的代码
#include<bits/stdc++.h>
using namespace std;
void findparent(int num,vector<int> s,int &p)
{
if(s[num]<0)
{
p=num;
return;
}
else
{
findparent(s[num],s,p);
}
}
int main()
{
int q;
cin>>q;
while(q)
{
int n;
cin>>n;
vector<int> v(n+1,0);
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
v[i]=x;
}
vector<int> s(n+1,-1);
for(int i=1;i<=n;i++)
{
int a=i;
int b=v[i];
int pa;
findparent(a,s,pa);
int pb;
findparent(b,s,pb);
if(pa!=pb)
{
//union(a,b);
if(s[pa]<=s[pb])//negative values being considered
{
s[pa]=s[pa]+s[pb];
s[pb]=pa;
}
else
{
s[pb]=s[pa]+s[pb];
s[pa]=pb;
}
}
}
vector<int> ans(n+1);
for(int i=1;i<=n;i++)
{
int p;
findparent(i,s,p);
ans[i]=-s[p];
cout<<ans[i]<<" ";
}
cout<<endl;
q--;
}
return 0;
}
//函数findparent返回值时给出错误答案的代码
#include<bits/stdc++.h>
using namespace std;
int findparent(int num,vector<int> s)
{
if(s[num]<0)
{
return num;
}
else
{
findparent(s[num],s);
}
}
int main()
{
int q;
cin>>q;
while(q)
{
int n;
cin>>n;
vector<int> v(n+1,0);
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
v[i]=x;
}
vector<int> s(n+1,-1);
for(int i=1;i<=n;i++)
{
int a=i;
int b=v[i];
int pa=findparent(a,s);
int pb=findparent(b,s);
if(pa!=pb)
{
//union(a,b);
if(s[pa]<=s[pb])//negative values being considered
{
s[pa]=s[pa]+s[pb];
s[pb]=pa;
}
else
{
s[pb]=s[pa]+s[pb];
s[pa]=pb;
}
}
}
vector<int> ans(n+1);
for(int i=1;i<=n;i++)
{
int p=findparent(i,s);
ans[i]=-s[p];
cout<<ans[i]<<" ";
}
cout<<endl;
q--;
}
return 0;
}
【问题讨论】:
-
"当函数 findparent 返回值时"
else的情况下不是这样。你没有收到任何编译器警告吗?
标签: c++ disjoint-sets