树上交换节点
给定一棵树,每个节点有一个权值。现在每次可以交换任意两个节点的权值,请问最少多少次交换可以使得每个节点的权值等于它的编号?
保证给出的权值是一个排列,也就是说保证一定有解。
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 256M,其他语言512M
输入描述:
第一行输入一个正整数
,代表树上的节点数量。
第二行输入
个正整数
,第
个正整数
是
号节点的权值,
互不相同。
接下来的
行,每行输入两个正整数
和
,代表
号节点和
号节点有一条边相连。
输出描述:
一个整数,代表最小的交换次数。
示例1
输入例子:
4 2 1 4 3 1 2 2 3 2 4
输出例子:
2
例子说明:
第一次交换1号节点和2号节点的权值,四个点的权值变成[1,2,4,3]
第二次交换3号节点和4号节点的权值,四个点的权值变成[1,2,3,4]
public class Program {public static void Main() {int n = int.Parse(System.Console.ReadLine());int[] a = new int[n + 1]; //输入下标对应数据string[] readArry = System.Console.ReadLine().Split();for (int i = 0; i < readArry.Length; i++) {a[i + 1] = int.Parse(readArry[i]);}for (int i = 0; i < n - 1; i++) {System.Console.ReadLine();//无需关系树结构 输入 }int ringNum = 0;//环数bool[] ergodic = new bool[n + 1];for (int i = 1; i < n + 1; i++) {if (!ergodic[i]) {ringNum++;int j = i;//环遍历下标while (!ergodic[j]) {ergodic[j] = true;if (j != a[j]) {j = a[j];}}}}System.Console.WriteLine(n-ringNum); } }