利用java类的思想和并查集的方法解决同一道算法题
2015-11-13 12:58
483 查看
这里是根据一个具体算法题来说明的,java类思想去和并查集方法,是两种不同的解题思路,它们各自有优点和缺点,只是根据使用者的个人习惯。本文会将两种解题方法都写一下,感兴趣的可以看一下。
Description
2013年春天的H7N9不亚于2003年的SARS,有上百人感染、几十人死亡。为减少传播,最好的策略是与感染者隔离。
在某个城市中,有一些社团。同一社团的人常彼此交往,一个人也可能参加不同的社团。为防止H7N9可能的传播,城市的疾病卫生防治中心列出了所有这些社团的成员,并作出如下隔离措施:
一旦一个社团的某个成员是H7N9病毒携带者(或怀疑对象),该社团的所有成员都是怀疑对象。
但是,他们发现,当一个人被确定是怀疑对象时确定所有怀疑对象是不容易的。你的任务是确定所有怀疑对象。
Input
输入有多种情况。
每种情况以一行上两个整数n、m开始,其中n是所有人数,m是社团数。可假定0 < n <= 3000、0 <= m <= 100。每个人有0到n-1的唯一一个标号,编号为0的人是怀疑对象。
接着有m行,每行是一个社团的信息。该行的第一个数是整数k,接着有k个整数表示该社团的k个人。所有整数之间有空格隔开。
当输入为n = 0、m = 0时表示输入结束,这种情况不必处理。两组数据之间有一个空行。
Output
对每种情况,一行输出所有被怀疑的人员的总是。
Sample Input
100 4
2 1 2
5 10 13 11 1214
2 0 1
2 99 2
Sample Output
4
解决这个算法题,一般用并查集的思想去解决。下面给出了利用java类的思想和java集合类的方法去解决这道算法题。
Description
2013年春天的H7N9不亚于2003年的SARS,有上百人感染、几十人死亡。为减少传播,最好的策略是与感染者隔离。
在某个城市中,有一些社团。同一社团的人常彼此交往,一个人也可能参加不同的社团。为防止H7N9可能的传播,城市的疾病卫生防治中心列出了所有这些社团的成员,并作出如下隔离措施:
一旦一个社团的某个成员是H7N9病毒携带者(或怀疑对象),该社团的所有成员都是怀疑对象。
但是,他们发现,当一个人被确定是怀疑对象时确定所有怀疑对象是不容易的。你的任务是确定所有怀疑对象。
Input
输入有多种情况。
每种情况以一行上两个整数n、m开始,其中n是所有人数,m是社团数。可假定0 < n <= 3000、0 <= m <= 100。每个人有0到n-1的唯一一个标号,编号为0的人是怀疑对象。
接着有m行,每行是一个社团的信息。该行的第一个数是整数k,接着有k个整数表示该社团的k个人。所有整数之间有空格隔开。
当输入为n = 0、m = 0时表示输入结束,这种情况不必处理。两组数据之间有一个空行。
Output
对每种情况,一行输出所有被怀疑的人员的总是。
Sample Input
100 4
2 1 2
5 10 13 11 1214
2 0 1
2 99 2
Sample Output
4
解决这个算法题,一般用并查集的思想去解决。下面给出了利用java类的思想和java集合类的方法去解决这道算法题。
package com.homework; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.Set; import java.util.TreeSet; /** * 定义社团成员对象 * @author Administrator * */ class Number{ List list = new ArrayList();//存放成员所参加过的社团编号 int id;//社员编号 } public class H7N9 { private static Scanner scanner; private static int n;//共有n个人员 private static int m;//有m个社团 private static int num; private static Set set; public static void main(String[] args) { scanner = new Scanner(System.in); n = scanner.nextInt(); m = scanner.nextInt(); while(n!=0||m!=0){ Number [] numbers = new Number ; for(int i=0;i<m;i++){ int num=scanner.nextInt(); for(int j=0;j<num;j++){ int x=scanner.nextInt(); if(numbers[x]==null){ Number number = new Number(); number.list.add(i); number.id = x; numbers[x] = number; }else{ numbers[x].list.add(i); } } } set = new TreeSet(); for(int i=0;i<numbers[0].list.size();i++){ set.add(numbers[0].list.get(i)); num++; } for(int t=1;t<numbers.length;t++){ if(numbers[t]!=null) for(int j=0;j<numbers[t].list.size();j++) if(set.contains(numbers[t].list.get(j))){ num++; for(int i=0;i<numbers[t].list.size();i++) set.add(numbers[t].list.get(i)); break; } } //输出结果 System.out.println(num); //初始化num准备进入下一次循环 num=0; n = scanner.nextInt(); m = scanner.nextInt(); } } }
下面是用并查集的方法解决该问题
package com.homework; import java.util.Scanner; public class H7N92 { private static Scanner scanner; private static int n;//输入的人数 private static int m;//社团数目 private static int[] array = new int[3000]; public static void main(String[] args) { scanner = new Scanner(System.in); while(scanner.hasNext()){ n = scanner.nextInt(); int[] num = new int ;//用于存放以该节点为父节点的集合中元素个数,初始都为1 for(int i=0;i<n;i++){ array[i] = -1; num[i] = 1; } m = scanner.nextInt(); for(int i=0;i<m;i++){ int[] number = new int[scanner.nextInt()];//每输入一组社团成员,定义一个临时数组存放 for(int j=0;j<number.length;j++){ number[j] = scanner.nextInt(); } //该for循环就是将这一个社团的人员并到同一个集合中去(这里有一个缺陷,就是每次输入的社团人数必须大于1个,由于时间问题暂时未优化) for(int j=1;j<number.length;j++){ int x = root(number[0]); int y = root(number[j]); if(x!=y){ array[y] = x; num[x]+=num[y]; } } } System.out.println(num[root(0)]); } } //并查集的核心思想 public static int root(int x){ if(array[x]==-1) return x; else{ int temp = root(array[x]); array[x] = temp; return temp; } } }
相关文章推荐
- java JDK 环境变量配置
- Java中的向前引用
- (转)java读取properties
- Spring的事务传播特性
- JAVA多态与异常处理课后作业
- JAVA中包和方法变量访问权限
- Eclipse Jetty调试时无法保存js文件
- java编程简单获取图片像素的方法
- Java 多态 后链接(late binding)与前链接(early binding) 向上转型(upcast)
- JDK并发工具类源码学习系列——ConcurrentSkipListMap
- java lock -----锁
- JDK并发工具类源码学习系列——ConcurrentSkipListMap(续)
- Java ArrayList 数组之间相互转换
- 从Eclipse ADT 切换到 Android Studio遇到的问题及解决办法汇总
- Spring的方法注入lookup-method(转)
- java--三目运算符 类型自动提升
- java并发编程实战
- java 集合的多线程
- 防止表单重复提交 java
- java对ArrayList排序代码示例