【海岛帝国系列赛】No.2 海岛帝国:“落汤鸡”市的黑帮危机
50200210海岛帝国:“落汤鸡”市的黑帮危机
【试题描述】
近几天,犯罪分子发现“药师傅”帝国的警力约等于0。(请见YSF的海岛帝国)于是开始猖狂了起来。他们选择了依山靠水(农村?)的“落汤鸡”市。开始抢劫财务,一天内发生了5起抢劫案,9起爆炸案,3起枪击案,12起绑架案!搞得YSF夜不能寐,况且每天还有那么多“怪物”要处理。于是,所有的责任都落在了“落汤鸡”市可怜的市长LTJ上。犯罪分子在LTJ市有了好多好多个窝点。市民开始惊慌起来,背井离乡。“郭同学”TONY由于YSF没还债而拒绝伸出援手。这时,YSF的“购物券”WHT提出了一个建议:请大名鼎鼎的“李易峰”探长来化解危机。于是,没主见的YSF照办了。不过,由于犯罪团伙庞大,作案频繁,数量众多,LTJ调查不清楚有几个犯罪团伙。不过,LYF探长还是搜集到了一些线索。助理YSM提出:强盗的同伙的同伙也是同伙,只有没有关系的才各自为政。请你帮帮可怜的LTJ、YSF、LYF,编一个程序来告诉他们有几个独立的犯罪团伙。
【输入要求】
* 第一行n表示强盗的人数,m表示警方搜集到的m条线索
* 接下来m行,每行两个整数a,b表示强盗a,b是同伙
【输出要求】
* 一个数:表示有几个独立的犯罪团伙
【输入实例】
10 9
1 2
3 4
5 2
4 6
2 6
8 7
9 7
1 6
2 4
【输出实例】
3
【其他说明】
无
【试题分析】
一看到什么团伙,什么信息这样的词,就一定知道要用神奇的“并查集”了。那我们先来看看:什么是并查集吧!
1. 简述
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。常常在使用中以森林来表示。
需要实现的操作有:合并两个集合,判断两个元素是否属于一个集合。
这里介绍的主要是普通的并查集,很多情况下使用的并查集是需要扩展的,根据使用情况的不同,有很多差别,这里仅仅是最基本的算法。
经典的find函数:
int findset(int x)
{
if(pa[x] != x)
{
int root = findset(pa[x]);
return pa[x] = root;
}
else
{
return x;
}
}
初始化:
void init() //初始化 该函数可以根据具体情况保存和初始化需要的内容
{
for(int i = ; i < MAX_SIZE; i++)
{
pa[i] = i;
}
}
1、Make_Set(x) 把每一个元素初始化为一个集合
初始化后每一个元素的父亲节点是它本身,每一个元素的祖先节点也是它本身(也可以根据情况而变)。
2、Find_Set(x) 查找一个元素所在的集合
查找一个元素所在的集合,其精髓是找到这个元素所在集合的祖先!这个才是并查集判断和合并的最终依据。
判断两个元素是否属于同一集合,只要看他们所在集合的祖先是否相同即可。
合并两个集合,也是使一个集合的祖先成为另一个集合的祖先,具体见示意图
3、Union(x,y) 合并x,y所在的两个集合
合并两个不相交集合操作很简单:
利用Find_Set找到其中两个集合的祖先,将一个集合的祖先指向另一个集合的祖先。如图
并查集的优化
1、Find_Set(x)时 路径压缩
寻找祖先时我们一般采用递归查找,但是当元素很多亦或是整棵树变为一条链时,每次Find_Set(x)都是O(n)的复杂度,有没有办法减小这个复杂度呢?
答案是肯定的,这就是路径压缩,即当我们经过"递推"找到祖先节点后,"回溯"的时候顺便将它的子孙节点都直接指向祖先,这样以后再次Find_Set(x)时复杂度就变成O(1)了,如下图所示;可见,路径压缩方便了以后的查找。
2、Union(x,y)时 按秩合并
即合并的时候将元素少的集合合并到元素多的集合中,这样合并之后树的高度会相对较小。
1int father[MAX]; /* father[x]表示x的父节点*/
2int rank[MAX]; /* rank[x]表示x的秩*/
3
4
5/* 初始化集合*/
6void Make_Set(int x)
7{
8 father[x] = x; //根据实际情况指定的父节点可变化
9 rank[x] = 0; //根据实际情况初始化秩也有所变化
10}
11
12
13/* 查找x元素所在的集合,回溯时压缩路径*/
14int Find_Set(int x)
15{
16 if (x != father[x])
17 {
18 father[x] = Find_Set(father[x]); //这个回溯时的压缩路径是精华
19 }
20 return father[x];
21}
22
23
24/*
25 按秩合并x,y所在的集合
26 下面的那个if else结构不是绝对的,具体根据情况变化
27 但是,宗旨是不变的即,按秩合并,实时更新秩。
28*/
29void Union(int x, int y)
30{
31 x = Find_Set(x);
32 y = Find_Set(y);
33 if (x == y) return;
34 if (rank[x] > rank[y])
35 {
36 father[y] = x;
37 }
38 else
39 {
40 if (rank[x] == rank[y])
41 {
42 rank[y]++;
43 }
44 father[x] = y;
45 }
46}
47
并且传说中的并查集按秩合并:
const int MAXSIZE = ;
int uset[MAXSIZE];
int rank[MAXSIZE]; void makeSet(int size) {
for(int i = ;i < size;i++) uset[i] = i;
for(int i = ;i < size;i++) rank[i] = ;
}
int find(int x) {
if (x != uset[x]) uset[x] = find(uset[x]);
return uset[x];
}
void unionSet(int x, int y) {
if ((x = find(x)) == (y = find(y))) return;
if (rank[x] > rank[y]) uset[y] = x;
else {
uset[x] = y;
if (rank[x] == rank[y]) rank[y]++;
}
}
这题只是并查集的基础,用到了find和merge合并
剩下的就貌似只有sum++了
【代码】
#include<iostream>
using namespace std;
int f[]={},n,m,k,sum=;
void init()
{
int i;
for(i=;i<=n;i++) f[i]=i;
return ;
}
int getf(int v)
{
if(f[v]==v) return v;
else
{
f[v]=getf(f[v]);
return f[v];
}
}
void merge(int v,int u)
{
int t1,t2;
t1=getf(v);
t2=getf(u);
if(t1!=t2) f[t2]=t1;
return ;
}
int main()
{
int i,x,y;
scanf("%d%d",&n,&m);
init();
for(i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
merge(x,y);
}
for(i=;i<=n;i++)
if(f[i]==i) sum++;
printf("%d\n",sum);
}
【海岛帝国系列赛】No.2 海岛帝国:“落汤鸡”市的黑帮危机的更多相关文章
- 【海岛帝国系列赛】No.7 海岛帝国:神圣之日
50237242海岛帝国:神圣之日 [试题描述] 战争持续九个月了.“购物券”WHT的军队还在跟恐怖分子僵持着.WHT和LJX已经向“公务员”告急,情况不宜乐观.YSF为守护帝国决定打开“够累 的”星 ...
- 【海岛帝国系列赛】No.6 海岛帝国:战争前线
50234237海岛帝国:战争前线 [试题描述] 总指挥官WHT出神入化的计谋虽然大有用武之地,但是聪明的恐怖分子们采取了城市核武器防御系统,可以有效地抵制WHT的炸弹.YSF对此头痛不已,因此 召开 ...
- 【海岛帝国系列赛】No.5 海岛帝国:独立之战
50229234海岛帝国:独立之战 [试题描述] 恐怖分子多年来一直如饥似渴地渴求“药师傅”帝国,但是,“里脊肉”BANNIE时刻在守护着这一方水土.从而使帝国日益强大.如今,BANNIE由于在 “牡 ...
- 【海岛帝国系列赛】No.4 海岛帝国:LYF的太空运输站
50212228海岛帝国:LYF的太空运输站 [试题描述] 最近,“购物券”WHT在“药师傅”帝国资源大会上提出了“SSTS”太空运输站计划.由于恐怖分子前些日子刚猖狂完,炸毁高楼无数,YSF不得不执 ...
- 【海岛帝国系列赛】No.3 海岛帝国:运输资源
海岛帝国:运输资源 [试题描述] YSF考虑到“药师傅”帝国现在资源极度不平均,于是,商讨启用南水北调工程.YZM为首席工程师.现在,YSF由于工作紧张,准备军用物资和民用物资.但他要时时关注运输工程 ...
- 【海岛帝国系列赛】No.1 海岛帝国:诞辰之日
50111117海岛帝国:诞辰之日 [试题描述] YSF自从上次“被盗投降”完(带着一大堆债)回去以后,YSF对“海盗”怀念至今,他想要建立一个“药师傅”海岛帝国. 今天,他要像“管理部”那样去探寻 ...
- 帝国cms7.0忘记后台管理账户用户名密码
最近刚登陆以前的网站,但是发现自己的后台管理用户名密码已经忘记,于是到帝国cms论坛里面找了一下解决方案,成功解决问题.特此分享一下解决成功经验. 原帖地址:http://bbs.phome.net/ ...
- Java开发笔记(四)Java帝国的度量衡
秦始皇统一中国之后,实行“书同文,车同轨”,把货币和各种度量衡都统一起来,从而缔造了一个秩序井然的帝国.既然统一度量衡是每个帝国都要做的事情,Java帝国也不例外,对于人生地不熟的初学者来说,只有认识 ...
- DEDEcms和帝国cms的几点比较
前言:最近有很多人问我DEDEcms和帝国cms哪个比较好,我之前用2个都做过站的,所以能够说出它们大体的区别. 声明:我在此说明的是我一贯用的两种建站体统的感受,没有诋毁或者提升哪个系统!两个系统都 ...
随机推荐
- git 初次使用
其实知道git很久了,也一度看了不少资料来学习指令.但是一直不明白到底我该咋办,我最疑惑的地方在于,本地代码是如何存储到远程服务器上的,那些指令在什么环境下执行,其实主要是目录问题.就是我在git s ...
- Fiddler-004-配置过滤器之-域名过滤
前文讲述了通过 Fiddler 进行网络抓包的一个小实例,具体敬请参阅博文: 有些细心的小主可能发现了,我们捕获的 HTTP请求 中有一些请求不是我们需要的,而是一些非必要数据,页面如下图所示:
- MFC之目录结构及消息流转(一)
跟上时代,用vs2010, 新建一个MFC应用程序Helloworld. 目录结构: 所有文件分为6个部分:解决方案相关文件.工程相关文件.应用程序头文件和源文件.资源文件.预编译头文件和编译链接生成 ...
- offset/client/scroll一些总结
offset/client/scroll一些总结 1.offset 首先offset共有五个值 1.offsetParent 2.offsetTop 3.offsetLeft 4.offsetWidt ...
- iOS单例模式
单例模式用于当一个类只能有一个实例的时候, 通常情况下这个“单例”代表的是某一个物理设备比如打印机,或是某种不可以有多个实例同时存在的虚拟资源或是系统属性比如一个程序的某个引擎或是数据.用单例模式加以 ...
- iOS发送短信
iPhone开发,发送短信的方法: iPhone开发中,发送短信方法有二: 1.URL Scheme,这样不可以设置短信内容 1 2 3 [[UIApplication sharedApplicati ...
- 替换SearchBar 键盘上的 搜索 按钮
for (UIView *searchBarSubview in [searchBar subviews]) { if ([searchBarSubview conformsToProt ...
- each的详解
首先我还是先观察w3c讲解: 先写一段代码,如图: 定义:each() 方法规定为每个匹配元素规定运行的函数. 提示:返回 false 可用于及早停止循环.(我在代码中加了return false,发 ...
- Linux和Windows路由配置
Linux和Windows路由配置 一.配置路由 1- 原则上一台主机只能有一条缺省路由.如果一台主机上有多个网段的话,请配置能够上网的那个网段的网关为缺省路由 Linux配置缺省路由: ...
- 微信公众平台开发(84) 小i机器人
很多朋友询问如何开发小黄鸡之类的智能聊天机器人,但遗憾的是小黄鸡接口申请页面在最近几个月里都无法访问,且使用时限制太大,我们找了另一个接口:小i机器人.本文介绍如何在微信公众平台中使用小i接口开发智能 ...