您的位置:首页 > 其它

Problem - D - Codeforces Fix a Tree

2016-07-20 12:44 162 查看
Problem - D - Codeforces Fix a Tree

看完第一名的代码,顿然醒悟。。。

我可以把所有单独的点全部当成线,那么只有线和环。

如果全是线的话,直接线的条数-1,便是操作数。

如果有环和线,环被打开的同时,接入到线上。那就是线和环的总数-1.

如果只有环的话,把所有的环打开,互相接入,共需n次操作。

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 2e5+5;
int cur[maxn];
int pre[maxn];
int Find(int x) {return pre[x] == x ? x : Find(pre[x]);}
int main()
{
int n;
scanf("%d",&n);
int thread = 0;
int ans = 0;
for(int i = 1; i<=n; i++) pre[i] = i;
for(int i = 1; i<=n; i++)
{
scanf("%d",&cur[i]);
if(cur[i]==i)
{
thread = i;
ans++;
}
else
{
int fx = Find(i);
int fy = Find(cur[i]);
if(fx == fy)
{
cur[i] = i;
ans++;
}
else
{
pre[fx] = fy;
}
}
}
if(thread==0) //全是环
{
for(int i = 1; i<=n; i++)
{
if(cur[i]==i)
{
thread = i;
break;
}
}
ans++;
}
printf("%d\n",ans-1);
for(int i = 1; i<=n; i++)
{
if(cur[i]==i) cur[i] = thread;
}
for(int i = 1; i<n; i++) printf("%d ",cur[i]);
printf("%d\n",cur
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: