系列文章目录
前言
本人最近再练习算法,所以会发布一些解题思路,希望大家多指教
一、题目描述
快递业务范围有 N 个站点,A 站点与 B 站点可以中转快递,则认为 A-B 站可达,如果 A-B 可达,B-C 可达,则 A-C 可达。
现在给 N 个站点编号 0、1、…n-1,用 s[i][j]表示 i-j 是否可达,s[i][j] = 1表示 i-j可达,s[i][j] = 0表示 i-j 不可达。
现用二维数组给定N个站点的可达关系,请计算至少选择从几个主站点出发,才能可达所有站点(覆盖所有站点业务)。
说明:s[i][j]与s[j][i]取值相同。
二、输入描述
第一行输入为 N,N表示站点个数。
之后 N 行表示站点之间的可达关系,第i行第j个数值表示编号为i和j之间是否可达。
1 < N < 10000。
三、输出描述
输出站点个数,表示至少需要多少个主站点。
示例:
输入:
4
1 1 1 1
1 1 1 0
1 1 1 0
1 0 0 1
四、Java代码
//存放每个站点及关联的所有站点信息
static Map<Integer, Set<Integer>> map;
//存放已处理的站点信息
static Set<Integer> set = new HashSet<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = Integer.parseInt(sc.nextLine());
map = new HashMap<>();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int n = sc.nextInt();
//初始化每个站点的对应关联站点
map.putIfAbsent(i, new HashSet<>());
if(i != j && n == 1){
map.get(i).add(j);
}
}
}
//初始化站点个数
int time = 0;
//遍历每个站点,获取最少的站点数
for (int i = 0; i < N; i++) {
if(set.contains(i)) continue;
Set<Integer> integers = map.get(i);
//将已经处理过的站点进行保存,避免在递归过程中重复处理
set.add(i);
//找出当前站点关联站点的关联站点
for(int ints : integers){
dfs(ints);
}
time++;
}
System.out.println(time);
}
private static void dfs(int i) {
if(set.contains(i)) return;
Set<Integer> integers = map.get(i);
set.add(i);
for(int ints : integers){
dfs(ints);
}
}
五、测试用例
输入:
4
1 1 1 1
1 1 1 0
1 1 1 0
1 0 0 1
输出: