九度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的主要内容,如果未能解决你的问题,请参考以下文章

九度OJ平台练习 —— 题目1011

&lt;九度 OJ&gt;题目1012:畅通project

九度oj 题目1397:查找数段

oj---九度oj--1012畅通工程

九度OJ-第5章-图论

九度OJ-题目1009:二叉搜索树