九度OJ平台练习 —— 题目1012
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了九度OJ平台练习 —— 题目1012相关的知识,希望对你有一定的参考价值。
这道题目设计到一点图论的知识,幸好我曾经学过图论。
思路是这样的:
当两个城市之间有道路能连通时,将这两个城市加入到同一个连通子集里,每个连通子集里的任意两个城市都是可以连通的。
比如存在两条路(1,2)和(2,3),那么1,2加入到一个连通子集s里,s = {1,2},2,3也加入到一个连通子集里,因为2已经在s中,那么把3加入到s中,s={1,2,3},根据s我们就可以得出,1和3是可以连通的。
处理完所有的路之后,我们得到j个连通子集,要使每个城市都能连通,即j个连通子集能够连通,至少需要j-1条边,将j个连通子集串起来。
我用数组来实现连通子集。
Java代码:
import java.util.*; public class Main{ public static void main(String args[]){ Scanner in = new Scanner(System.in); while(in.hasNext()){ int n = in.nextInt(); if(n == 0) break; int m = in.nextInt(); int fa[] = new int[n+1]; //用于模拟连通子集 int vist[] = new int[n+1]; //用于统计连通子集的个数 //初始化
for(int i = 0; i <= n; i++){ fa[i] = i; vist[i] = 0; }
//处理每一条路 while(m-- > 0){ int a = in.nextInt(); int b = in.nextInt(); merge(a,b,fa); }
//因为find(i,fa)的结果是连通子集的标识,有多少个连通子集,vist数组就有多少个1 for(int i = 1; i <= n; i++){ vist[find(i,fa)] = 1; } int count = 0;
//统计连通子集的个数 for(int i = 1; i <= n; i++){ if(vist[i] == 1) count++; } System.out.println(count-1); } in.close(); }
//将a和b加入到同一个连通子集里,用fa[b]的值标识这个连通子集。每个连通子集都有唯一的标识。
//对于连通子集里的每个元素i,调用find(i,fa)时,最终都会得到该标识。 public static void merge(int a, int b, int fa[]){ a = find(a,fa); b = find(b,fa); fa[a] = fa[b]; }
//递归查找x的标识 public static int find(int x, int fa[]){ if(x == fa[x]) return x; else return find(fa[x],fa); } }
以上是关于九度OJ平台练习 —— 题目1012的主要内容,如果未能解决你的问题,请参考以下文章