题目链接:http://codeforces.com/problemset/problem/698/B
题意:告诉你n个节点当前的父节点,修改最少的点的父节点使之变成一棵有根树。
思路:拆环。
题解:http://codeforces.com/blog/entry/46148
代码:
#include <cstdio> const int maxn = 200200; int f[maxn], vis[maxn], n, s, cnt, idx; int Find(int x) { vis[x] = ++ idx; while (!vis[ f[x] ]) { x = f[x]; vis[x] = idx; } if (vis[ f[x] ] == idx) { if (s == 0) s = x; if (f[x] != s) { f[x] = s; cnt ++; } } } int main() { scanf("%d", &n); for (int i = 1; i <= n; i ++) scanf("%d" , f + i); for (int i = 1; i <= n; i ++) if (i == f[i]) s = i; for (int i = 1; i <= n; i ++) if (!vis[i]) Find(i); printf("%d\n", cnt); for (int i = 1; i <= n; i ++) printf("%d ", f[i]); return 0; }