Luogu P1892 [BOI2003]团伙
P1892 [BOI2003]团伙
题目描述
1920年的芝加哥,出现了一群强盗。如果两个强盗遇上了,那么他们要么是朋友,要么是敌人。而且有一点是肯定的,就是:
我朋友的朋友是我的朋友;
我敌人的敌人也是我的朋友。
两个强盗是同一团伙的条件是当且仅当他们是朋友。现在给你一些关于强盗们的信息,问你最多有多少个强盗团伙。
输入输出格式
输入格式:
输入文件gangs.in的第一行是一个整数N(2<=N<=1000),表示强盗的个数(从1编号到N)。 第二行M(1<=M<=5000),表示关于强盗的信息条数。 以下M行,每行可能是F p q或是E p q(1<=p q<=N),F表示p和q是朋友,E表示p和q是敌人。输入数据保证不会产生信息的矛盾。
输出格式:
输出文件gangs.out只有一行,表示最大可能的团伙数。
输入输出样例
6
4
E 1 4
F 3 5
F 4 6
E 1 2
3
先说一下思路:
对于只有朋友信息的数据就不用说了。对于敌人的信息,我们可以给每一个人i设置一个敌人集合E[i],当输入i和j时,我们就把i和E[j]合并,把j和E[i]合并。
值得一提的是,要注意空集的处理,所谓空集就是一开始的时候,每个人都没有敌人。
昨天晚上做了一晚上卡在了50分,今天又接着来啃,问同学,同学说我的想法很对,叫我自己慢慢调(WCNM我要是调的出来就不找你了)
没办法,慢慢找喽。
先给大家看看我的50分的代码。
#include <iostream>
#include <cstdio> using namespace std; int n, m, Ans, x, y; int f[1008], E[1008]; char C; bool vis[1008]; int find(int x) {
if(x == f[x]) return f[x];
else return f[x] = find(f[x]);
} int main() {
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++) f[i] = i;
for(int i=1; i<=m; i++) {
cin>>C>>x>>y;
int xx, yy;
if(C == 'E') {
if(E[x] != 0) {
f[y] = find(E[x]);
}
if(E[y] != 0) {
f[x] = find(E[y]);
}
E[x] = y, E[y] = x;
}
if(C == 'F') {
f[x] = find(y);
}
}
for(int i=1; i<=n; i++) {
if(!vis[find(i)]) {
vis[find(i)] = 1;
Ans++;
}
}
printf("%d", Ans);
}
不知道大家看出什么问题了没。
没看出的同学可要小心了,
看一下我的合并集合时候的操作,是不是把之前合并好的集合都打乱了。
为什么?因为我合并时修改的是f[x]的值,而不是f[find(x)]的值,这就会导致很可怕的错误。
往后的此类操作都是这样的。
好了,说到这里该放上AC的代码了
#include <iostream>
#include <cstdio> using namespace std; int n, m, Ans, x, y; int f[1008], E[1008]; char C; bool vis[1008]; int find(int x) {
if(x == f[x]) return x;
else return f[x] = find(f[x]);
} int main() {
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++) f[i] = i;
for(int i=1; i<=m; i++) {
cin>>C>>x>>y;
if(C == 'E') {
if(E[x] != 0) {
f[find(y)] = find(E[x]);
}
else E[x] = find(y);
if(E[y] != 0) {
f[find(x)] = find(E[y]);
}
else E[y] = find(x);
}
if(C == 'F') {
f[find(x)] = find(y);
}
}
for(int i=1; i<=n; i++) {
if(!vis[find(i)]) {
vis[find(i)] = 1;
Ans++;
}
}
printf("%d", Ans);
}
Luogu P1892 [BOI2003]团伙的更多相关文章
- 洛谷 P1892 [BOI2003]团伙(并查集)
嗯... 题目链接:https://www.luogu.org/problemnew/show/P1892 通过读题可以很清楚的发现这是一个并查集的题,并且要有两个集合: 若他们p和q是朋友,则存入第 ...
- P1892 [BOI2003]团伙 并查集
题目描述 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的朋友是我的朋友: 我敌人的敌人也是我的朋友. 两个强盗是同一团伙的 ...
- Luogu P1892 P1525 团伙 关押罪犯
(怎么都是抓罪犯 怪不得写法差不多) 团伙 关押罪犯 并查集.以"敌人的敌人是朋友"的思路来处理.所以增加一个e/E数组来存储敌人. 关押罪犯还用到了贪心的思路.将冲突值从大到小排 ...
- 洛谷 P1892 [BOI2003]团伙
题目描述 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的朋友是我的朋友: 我敌人的敌人也是我的朋友. 两个强盗是同一团伙的 ...
- 【题解】P1892 [BOI2003]团伙-C++
原题传送门 前置知识:并查集,不会的补了再来. 这道题只是在并查集的基础上多了一个操作而已. 这种操作,叫做反集(就先这么叫着) 题目里有一种关系是互为朋友,这很好理解,把互为朋友的两个点合并就可以了 ...
- 洛谷 P1892 [BOI2003]团伙(种类并查集)
传送门 解题思路 用并查集f存朋友关系,一个数组e存的是敌人关系,是一个辅助数组,所以叫做种类并查集. 当p和q是朋友时,直接合并,但是当是敌人时,需要一些操作. 当p还没有敌人时(即p的敌人是自己) ...
- Luogu P1892 团伙
Luogu P1892 团伙 这是道很简单的并查集-- 不,它并不简单. 这道题考了一个叫做反集的东西. 也就是说: 如果$a$和$b$是敌人,合并$n+b$和$a$,$n+a$和$b$: 如果$c$ ...
- [洛谷P1892][codevs2597]团伙
题目大意:有n个强盗,他们有这样的关系:1.朋友的朋友是朋友:2.敌人的敌人是朋友. 两个人是朋友,则他们在一个团伙中,是敌人则在不同团伙中. 现在给出一些朋友或敌人的关系,问最多有多少团伙.输入保证 ...
- [BOI2003]团伙
题目描述 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的朋友是我的朋友: 我敌人的敌人也是我的朋友. 两个强盗是同一团伙的 ...
随机推荐
- 使用JavaScript开发IE浏览器本地插件实例
使用JavaScript开发IE浏览器本地插件实例 投稿:junjie 字体:[增加 减小] 类型:转载 时间:2015-02-18我要评论 这篇文章主要介绍了使用JavaScript开发IE浏览器本 ...
- Android开发之使用sqlite3工具操作数据库的两种方式
使用 sqlite3 工具操作数据库的两种方式 请尊重他人的劳动成果,转载请注明出处:Android开发之使用sqlite3工具操作数据库的两种方式 http://blog.csdn.net/feng ...
- LeetCode 290. Word Pattern (词语模式)
Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...
- 创建FTP服务
Step1: Create a FTP folder in your C disk, named “AutomationReport” Step2: Install IIS components. ...
- XAML实例教程系列 - XAML传递参数到值转换类实例 八
Kevin Fan分享开发经验,记录开发点滴 XAML实例教程系列 - XAML传递参数到值转换类实例 2012-06-28 05:25 by jv9, 508 阅读, 0 评论, 收藏, 编辑 继上 ...
- 【POJ 2689】 Prime Distance
[题目链接] http://poj.org/problem?id=2689 [算法] 我们知道,一个在区间[l,r]中的合数的最小质因子必然不超过sqrt(r) 那么,先暴力筛出1-50000中的质数 ...
- [Swift通天遁地]二、表格表单-(11)创建星期选项表单和拥有浮动标签的文本框
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- BZOJ 4811 树链剖分+线段树
思路: 感觉这题也可神了.. (还是我太弱) 首先发现每一位不会互相影响,可以把每一位分开考虑,然后用树链剖分或者LCT维护这个树 修改直接修改,询问的时候算出来每一位填0,1经过这条链的变换之后得到 ...
- Centos7基本命令
shell基本命令 linux命令行的组成结构 linux系统命令操作语法格式 命令 空格 参数 空格 文件路径或者需要处理的内容 rm -rf /tmp/* ls -la /home ...
- 胖ap和瘦ap的区别
一,什么是AP,胖瘦AP如何区分? 先说说AP的概念.AP是Access Point的简称,即无线接入点,其作用是把局域网里通过双绞线传输的有线信号(即电信号)经过编译,转换成无线电信号传 ...