晚上写残了,来补一下。
思路:因为要变成一棵树,那肯定只有一个根,所以加入这个图里有n个树或环,那就要把其中的n-1个树或环接到另外一个树下面。
所以这个题就是求这个图有几个根,然后把所有的根移到同一个根下面就好了。
先用并查集找根,如果已经有现成的树根了,就把别的环和根移到这下面,如果没有现成的树根,也就是说,都是环,那么就把一个环变成树根,别的在连过来。
代码:
//************************************************************************//
//*Author : Handsome How *//
//************************************************************************//
//#pragma comment(linker, "/STA CK:1024000000,1024000000")
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <ctime>
#if defined(_MSC_VER) || __cplusplus > 199711L
#define aut(r,v) auto r = (v)
#else
#define aut(r,v) __typeof(v) r = (v)
#endif
#define foreach(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it)
#define fur(i,a,b) for(int i=(a);i<=(b);i++)
#define furr(i,a,b) for(int i=(a);i>=(b);i--)
#define cl(a) memset((a),0,sizeof(a))
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#ifdef HandsomeHow
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define dbg(x) cout << #x << " = " << x << endl
#else
#define debug(...)
#define dbg(x)
#endif
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const int mod=1000000007;
const double pi=acos(-1);
inline void gn(long long&x){
int sg=1;char c;while(((c=getchar())<'0'||c>'9')&&c!='-');c=='-'?(sg=-1,x=0):(x=c-'0');
while((c=getchar())>='0'&&c<='9')x=x*10+c-'0';x*=sg;
}
inline void gn(int&x){long long t;gn(t);x=t;}
inline void gn(unsigned long long&x){long long t;gn(t);x=t;}
int gcd(int a,int b){return a? gcd(b%a,a):b;}
ll powmod(ll a,ll x,ll mod){ll t=1ll;while(x){if(x&1)t=t*a%mod;a=a*a%mod;x>>=1;}return t;}
// (づ°ω°)づe★
//-----------------------------------------------------------------
const int maxn = 222222;
int p[maxn], v[maxn];
int n,rroot,subroot;
int findf(int x){
if(x == p[x]) return x;
int t = findf(p[x]);
p[x] = t;
return t;
}
void merge(int a, int b){
a = findf(a); b = findf(b);
if(a != b) p[a] = b;
}
int main(){
#ifdef HandsomeHow
//freopen("E:\\data.in","r",stdin);
//freopen("E:\\data.out","w",stdout);
time_t beginttt = clock();
#endif
gn(n);
rroot = -1;
fur(i,1,n) p[i] = i;
fur(i,1,n){
gn(v[i]);
if(v[i] == i) rroot = i;
merge(i,v[i]);
}
fur(i,1,n) if(findf(i) == i) subroot = i;
if(rroot == -1) rroot = subroot; //是否有现成的树根
int ans = 0;
if(v[rroot] != rroot){
ans++;
v[rroot] = rroot;
}
for(int i = 1; i <= n; ++i){
if(findf(i) == i && i != rroot){
ans++;
v[i] = rroot;
}
}
printf("%d\n",ans);
fur(i,1,n) printf("%d ",v[i]);
puts("");
#ifdef HandsomeHow
time_t endttt = clock();
debug("time: %d\n",(int)(endttt - beginttt));
#endif
return 0;
}