Free Figurines
分析:
-
这题是个套娃
-
可以转成一个含有多条链的有向图
-
从新图到旧图,让我们求最少的操作次数
考虑不用改变的地方:
-
对于每一条链,从旧链转换到新链,首先它们的起点肯定还要一样(因为这是个套娃,最下面的才可以不用变,上面的要一个一个的拿出来)
然后就可以从起点往后找,直到两个链的元素不相同
-
-
思路转换:若直接考虑去一个一个的加操作数,会很复杂,考虑用容斥
最劣的方法就是先将旧图的所有边断开,再将新图的所有边连上
再减去所有共有的边,就是 a n s ans ans
-
如何找共有的边
-
首先,找到所有链的起点
-
在新图上,枚举两个图共有的起点(一定要满足共有的起点才行)
-
按条件往后查一遍即可
-
#include <bits/stdc++.h>
using namespace std;
const int N=100005;
int a[N],b[N],vis[N];
signed main()
{
int n;
cin>>n;
int ans=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]) ans++,vis[a[i]]=1; // 将儿子(非起点)打标记
}
for(int i=1;i<=n;i++)
{
cin>>b[i];
if(b[i]) ans++,vis[b[i]]=1; // 将儿子(非起点)打标记
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
int u=i;
while(a[u] && a[u]==b[u])
{
ans-=2; // 共有的一条边,新图旧图上都对ans有贡献1
vis[u]=1;
u=a[u];
}
}
}
cout<<ans<<endl;
}