https://codeforces.com/problemset/problem/698/B
Title:
Repair a tree, give the parent node of a tree, and then it may have a ring and become a graph, or the root node is not 1.
Ideas:
Considering the influence of the ring, dfs is needed to judge the ring. Then save the end points on the ring. If there is no ring, just put one. Then connect the different connected blocks.
A very detailed place
When there is a single point of connection, connect the side to the single point
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL fa[maxn];
LL dfn[maxn],tot=0;
vector<LL>p;
vector<LL>g[maxn];
bool flag=1;
///无环保持,有环将环上的端点拆了
void dfs(LL u,LL last){
dfn[u]=++tot;
for(LL i=0;i<g[u].size();i++){
LL v=g[u][i];
if(v==last) continue;
if(dfn[v]&&flag==1){
flag=0;
p.push_back(v);
}
else if(!dfn[v]){
dfs(v,u);
}
}
}
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL n;cin>>n;
for(LL i=1;i<=n;i++){
LL u=i;LL v;cin>>v;
fa[u]=v;
g[u].push_back(v);
g[v].push_back(u);
}
for(LL i=1;i<=n;i++){
if(!dfn[i]){
flag=1;tot=0;
dfs(i,-1);
if(flag==1) p.push_back(i);
}
}
LL ans=0;
///LL anc=(*p.rbegin());
LL anc=0;
for(LL i=0;i<p.size();i++){
if(fa[p[i]]==p[i]){
anc=p[i];
break;
}
else anc=p[i];
}
for(LL i=0;i<p.size();i++){
if(fa[p[i]]!=anc) ans++;
fa[p[i]]=anc;
}
cout<<ans<<"\n";
for(LL i=1;i<=n;i++){
cout<<fa[i]<<" ";
}
cout<<"\n";
return 0;
}