【海岛帝国系列赛】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)时 按秩合并
即合并的时候将元素少的集合合并到元素多的集合中,这样合并之后树的高度会相对较小。
1
int father[MAX]; /* father[x]表示x的父节点*/
2
int rank[MAX]; /* rank[x]表示x的秩*/
3
4
5
/* 初始化集合*/
6
void Make_Set(int x)
7
{
8
father[x] = x; //根据实际情况指定的父节点可变化
9
rank[x] = 0; //根据实际情况初始化秩也有所变化
10
}
11
12
13
/* 查找x元素所在的集合,回溯时压缩路径*/
14
int 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
*/
29
void 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个都做过站的,所以能够说出它们大体的区别. 声明:我在此说明的是我一贯用的两种建站体统的感受,没有诋毁或者提升哪个系统!两个系统都 ...
随机推荐
- backgroundworker的应用
一种情况是当凭证界面加载时,因为加载项比较多,辅助项的处理,可以应用backgroundworker启用另一线程进行加载,不影响当前界面的显示,提高响应速度. 情况2 是月末结转余额时,因为用时间较长 ...
- 记录:在老XPS1330上安装CentOS7
下图是设置时的图片,注意分区设置. 下图是安装成功的画面. 下图是在Gnome桌面环境打开Firefox上本博客的画面. 注意点: 1.安装时没啥特殊的,就两点,一是要分区设置好,图省事就让自动分区: ...
- 在Fedora8上安装jdk-7u25-linux-i586.rpm的步骤
按:我们身处一个信息爆炸的年代,当有事不决时,打开搜索引擎瞬息间就能得到海量的答案.但是,这未必会让你的问题迎刃而解,因此很多“答案”会把你引向错误的方向,浪费你的时间.希望搜索引擎能有所改进,对明确 ...
- Definition Questions
What is the relationship and differences between processes and threads? A process usually represent ...
- Sersync实现触发式文件同步 替代inotify和rsync
Sersync实现触发式文件同步 替代inotify和rsync Pyinotify是一个Python模块,用来监测文件系统的变化. Pyinotify依赖于Linux内核的功能—inotify(内核 ...
- Android TimePickerDialog样式配置与TimePicker模式选择
习惯性的,把要说的内容先总结一下: TimePicker有两种模式:spinner 和clock,可通过如下方式配置: <TimePicker android:timePickerMode = ...
- shell中&&和||的使用方法_转
shell中&&和||的使用方法 &&运算符: command1 && command2 &&左边的命令(命令1)返回真(即返 ...
- ADB 在 Android SDK 的中的路径
以前 adb.exe 是在 sdk/tools 目录下 现在 安装 sdk 之后, 需要打开 SDK Manager 下载 `Android SDK Platform-tools` 然后, 在 sdk ...
- CString + UINT Error:有多个运算符"+="与这些操作数匹配
在OnChar中,参数UINT nChar 有一个CString str,现在执行 str += nChar报错:Error:有多个运算符"+="与这些操作数匹配 解决办法:把UI ...
- gradient color
http://www.cnblogs.com/YouXianMing/p/3793913.html layer 不能自动autolay, 只能在viewDidLayout里面设置宽度 - (void) ...