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[n]); return 0; }
时间: 2024-10-14 14:05:21