题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1232

题目描述

Problem Description

某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?

Input

测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。

注意:两个城市之间可以有多条道路相通,也就是说

3 3

1 2

1 2

2 1

这种输入也是合法的

当N为0时,输入结束,该用例不被处理。

Output

对每个测试用例,在1行里输出最少还需要建设的道路数目。

Sample Input

4 2

1 3

4 3

3 3

1 2

1 3

2 3

5 2

1 2

3 5

999 0

0

Sample Output

1

0

2

998

解体思路

求连通分支数,道路数即为联通分支数-1,使用并查集。

相关知识:并查集union-find

作用

维护无向图的连通性。

核心思想

  • (查)判断两个结点是否连通:

    • 每个连通集用一个代表节点标志集合。用树形结构存储一个连通集,根节点即为这个连通集的标志节点。若两个节点的根节点相同,说明两个节点属于同一个连通集。
    • 路径压缩:为维持树的高度尽量小,当查找两个节点属于同一个连通集后,把途径的所有节点的父节点都直接赋值为标志节点。
    • 时间复杂度:使用路径压缩后,查找时间复杂度可近似认为是常数。
  • (并)将两个节点所在集合连通:将一个节点的根节点挂在另一个节点的根节点上。具体地,高度小的树挂在高度搞的树的下面,保证树不退化,即高度维持稳定。具体谁和谁连通,依题目而定。

实现

存储结构:

  • pre[节点数]:pre数组维护了多棵树,保存当前结点的父结点。若pre[i]=i,则表示节点i为
  • rank[节点数]:表示以当前结点为根的树的高度。
  • value[节点数] (可选):存储当前结点的值,若值为角标,则不需要该数组。

操作方法:

  • init():初始化pre[i]=i;rank[I]=1;
  • find():查
  • unite():并

todo

学习并查集进阶

http://www.cnblogs.com/xzxl/p/7341536.html

代码

import java.util.HashSet;
import java.util.Scanner; public class Main {
public final static int MAXN=1005;
public static int[] pre=new int[MAXN];
public static int[] rank=new int[MAXN]; 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();
init(N);
while(M-->0) {
unite(in.nextInt(),in.nextInt());
}
HashSet<Integer> rootSet=new HashSet<Integer>();
for(int i=1;i<=N;++i) {
int root=find(i);
if(!rootSet.contains(root)) {
rootSet.add(root);
}
}
System.out.println(rootSet.size()-1);
}
} public static void init(int N) {
for(int i=1;i<=N;++i) {
pre[i]=i;
rank[i]=1;
}
} public static int find(int x) {
return pre[x]==x?x:(pre[x]=find(pre[x]));
} public static void unite(int x,int y) {
int xRoot=find(x);
int yRoot=find(y);
if(xRoot!=yRoot) {
if(rank[xRoot]>rank[yRoot]) {
pre[yRoot]=xRoot; }
else {
if(rank[xRoot]==rank[yRoot]) {
++rank[yRoot];
}
pre[xRoot]=yRoot;
}
}
}
}

reference

https://www.cnblogs.com/xzxl/p/7226557.html

[HDOJ1232]畅通工程(并查集)的更多相关文章

  1. HDU1232 畅通工程 并查集

    畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  2. ACM: 继续畅通工程-并查集-最小生成树-解题报告

    继续畅通工程 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Descri ...

  3. ACM: 畅通工程-并查集-解题报告

    畅通工程 Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description 某省调查城镇交通状况 ...

  4. B - 畅通工程(并查集)

    对并查集理解之后就可以做这种题了,虽说这种题做的不多,这道题做过才这么快搞定,可是还是挺happy滴,加油 Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接 ...

  5. NSOJ 畅通工程(并查集)

    某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可). ...

  6. hdu 1233 还是畅通工程 并查集or最小生成树

    某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路 ...

  7. hdu1232 畅通工程 并查集的 应用

    畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  8. hdu 1863 畅通工程 (并查集+最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1863 畅通工程 Time Limit: 1000/1000 MS (Java/Others)    M ...

  9. HDU - 1232 畅通工程-并查集模板

    某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可). ...

随机推荐

  1. 什么是BFC?看这一篇就够了

    BFC 定义 BFC(Block formatting context)直译为"块级格式化上下文".它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的 ...

  2. 关于Exceptionless日志收集框架会被Fiddler抓包,从而获取到ApiKey的问题

    关于Exceptionless日志收集框架会被Fiddler抓包,从而获取到ApiKey的问题 环境:Exceptionless5.0.0.Linux.WPF客户端.Fiddler 问题:在使用Exc ...

  3. hook框架-frida简单使用模板以及frida相关接口

    一目录结构 ├── test.py #py脚本 └── test.js #js脚本 一.py脚本 test.py import frida import sys #连接设备app dev=frida. ...

  4. dcoker 小应用(一)

    docker 创建Ubuntu系统 1.创建Dockerfile #ubuntu:14.04 image FROM ubuntu:14.04 MAINTAINER XXX, xxx@xxx.com R ...

  5. 团队作业4:第三篇Scrum冲刺博客(歪瑞古德小队)

    目录 一.Daily Scrum Meeting 1.1 会议照片 1.2 项目进展 二.项目燃尽图 三.签入记录 3.1 代码/文档签入记录 3.2 Code Review 记录 3.3 issue ...

  6. python 列表和字典的引用与复制(copy)

    列表或字典的引用: 引用针对变量的时候,传递引用后,对引用后的对象的值进行改变是不会影响到原值的:而列表不一样如: spam =42 cheese = spam spam =100 print(spa ...

  7. 关于c++11 memory order的理解

    关于C++memory_order的理解 看了c++并发编程实战的内存模型部分后,一直对memory_order不太懂,今天在知乎发现了百度的brpc,恰好有关于原子操作的文档,感觉解释的很好.为了加 ...

  8. DevOps系列(2)-SonarQube之PostgreSQL

    上一篇从整体上讲了下DevOps大概涉及到了哪些内容,以及主要工作流程,接下来我们将分步详细介绍各个部分的使用. 概览 首先从 SonarQube 开始说起,SonarQube 是一个可用于检测重复代 ...

  9. 区块链入门到实战(30)之Solidity – 基础语法

    一个 Solidity 源文件可以包含任意数量的合约定义.import指令和pragma指令. 让我们从一个简单的 Solidity 源程序开始.下面是一个 Solidity 源文件的例子: prag ...

  10. 技术揭秘:华为云DLI背后的核心计算引擎

    摘要:介绍隐藏在华为云数据湖探索服务背后的核心计算引擎Spark,玩转DLI,,轻松完成大数据的分析处理. 本文主要给大家介绍隐藏在华为云数据湖探索服务(后文简称DLI)背后的核心计算引擎——Spar ...