认老乡
题目描述
大学的同学来自全国各地,对于远离家乡步入陌生大学校园的大一新生来说,碰到老乡是多么激动的一件事,于是大家都热衷于问身边的同学是否与自己同乡,来自新疆的小赛尤其热衷。但是大家都不告诉小赛他们来自哪里,只是说与谁同乡,从所给的信息中,你能告诉小赛有多少人确定是她的同乡吗?
输入
每个测试实例首先包括2个整数,N(1 <= N <= 1000),M(0 <= M <= N*(N-1)/2),代表现有N个人(用1~N编号)和M组关系;
在接下来的M行里,每行包括2个整数,a,b,代表a跟b是同乡;
当N = 0,M = 0输入结束;
已知1表示小赛本人。
样例输入
3 1
2 3
5 4
1 2
3 4
2 5
3 2
0 0
输出
对于每个测试实例,输出一个整数,代表确定是小赛同乡的人数。
样例输出
0
4
解题思路:
使用并查集算法。
参考:http://blog.csdn.net/dellaserss/article/details/7724401/
http://blog.csdn.net/u013486414/article/details/38682057
以第二个输入测试用例为例:
主要思想:我的老乡是我的老乡,我的老乡的老乡也是我的老乡,我的老乡的老乡的老乡…也是我的老乡。老乡关系就比一个树,每次在遍历他们的关系的时候,设置他与这个关系里面的根节点(老乡)为自己的老乡(直接互连)。
以上面的第二个输入测试为例:
5 4
[0, 1, 2, 3, 4, 5] //初始化,设置每个人的老乡都是自己
1 2
[0, 1, 1, 3, 4, 5]//根据输入关系,设置第2个人的老乡(他的上一级)为第一个人
3 4
[0, 1, 1, 3, 3, 5]//同上,设置第4个人的老乡为第3个人
2 5
[0, 1, 1, 3, 3, 1]//同上,本来应该设置第5个人的老乡为第2个人,但是第2个人的老乡为第1个人,所以直接设置第5个人的老乡就是第1个人
3 2
[0, 3, 3, 3, 3, 3]//同上,本来第二个人的老乡应该是第三个人,但是第三个人的老乡已经是老乡关系中的根节点
最后计算,与第一个人有相同根节点的老乡有多少个
java实现:
import java.util.Arrays;
import java.util.Scanner;
public class BingQuetyDemo {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int M = scan.nextInt();
while (N != 0 || M != 0) {
int[] value = new int[N + 1];
int result = -1;
for (int i = 1; i < value.length; i++) {
value[i] = i;
}
System.out.println(Arrays.toString(value));
for (int i = 0; i < M; i++) {
int a = scan.nextInt();
int b = scan.nextInt();
int tmp = value[b];
for (int j = 1; j < value.length; j++) {
if (value[j] == tmp) value[j] = value[a];
}
System.out.println(Arrays.toString(value));
}
for (int i = 1; i < value.length; i++) {
if (value[i] == value[1]) result++;
}
System.out.println(result);
N = scan.nextInt();
M = scan.nextInt();
}
scan.close();
}
}