码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-05-18 09:12:22      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

这道题目设计到一点图论的知识,幸好我曾经学过图论。

思路是这样的:

当两个城市之间有道路能连通时,将这两个城市加入到同一个连通子集里,每个连通子集里的任意两个城市都是可以连通的。

比如存在两条路(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

标签:

原文地址:http://www.cnblogs.com/mudao/p/5503925.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!