[LUOGU] 1892 团伙
题目描述
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只有一行,表示最大可能的团伙数。
输入输出样例
输入样例#1: 复制
6
4
E 1 4
F 3 5
F 4 6
E 1 2
输出样例#1: 复制
3
最难处理的是敌人这块问题,最开始想到用一个敌人邻接表存下所有的直接联系的敌人,然后每次加入敌人的时候将待加入的点和通过该点到达的所有点作为朋友并起来,一开始只有90分,忽略了无向图(这数据不行啊。。),代码并不算太慢。
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#define MAXN 20000
using namespace std;
//priority_queue
int m,n;
int fa[MAXN];
int ans[MAXN];
struct Edge{
int next,to;
}enode,e[MAXN];
int ct=0;
int head[MAXN];
//vector<Edge> e;
//inline void add(int x,int y){
// head[x]=e.size() ;
// enode.to = y;
// enode.next = head[x];
// e.push_back(enode);
//
//}
void add(int x,int y){
e[++ct].next= head[x];
e[ct].to = y;
head[x]=ct;
}
int fnd(int x){
// cout<<x<<endl;
if(fa[x]==x) return x;
return fa[x]=fnd(fa[x]);
}
void cat(int x, int y){
// x=fnd(x);
// y=fnd(y);
fa[y]=x;
}
int main(){
// freopen("testdata.in","r",stdin);
memset(head,-1,sizeof(head));
cin>>n>>m;
char sta;
int x,y;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++){
// scanf("%c %d %d",&sta,&x,&y);
cin>>sta>>x>>y;
// cout<<"XXX: "<<x<<" "<<y<<endl;
if(sta=='E'){
for(int j=head[x];j!=-1;j=e[j].next){
// cout<<"J:"<<j<<endl;
int u=fnd(e[j].to),v=fnd(y);
if(u!=v) cat(u,v);
}
for(int j=head[y];j!=-1;j=e[j].next){//LSM庇佑
int u=fnd(e[j].to),v=fnd(x);
if(u!=v) cat(u,v);
}
add(x,y);
//
add(y,x);
}else{
int u=fnd(x),v=fnd(y);
if(u!=v) cat(u,v);
}
}
for(int i=1;i<=n;i++){
ans[i]=fnd(i);
}
sort(ans+1,ans+1+n);
int cnt=1;
for(int i=1;i<n;i++) if(ans[i]!=ans[i+1]) cnt++;
cout<<cnt;
return 0;
}
嗯。。最后那块处理计数的部分实在是丑陋。
然后静静教了一种神奇的方法,并查集的补集。
通过把敌人(i+N)作为朋友来加入,大大简化了代码,所有人都是朋友!
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#define MAXN 5005
using namespace std;
//priority_queue
int m,n;
int fa[MAXN];
int fnd(int x){
if(x==fa[x]) return x;
return fa[x]=fnd(fa[x]);
}
void cat(int x,int y){
x=fnd(x);
y=fnd(y);
fa[y]=x;
}
bool vis[MAXN];
int main(){
cin>>n>>m;
for(int i=1;i<=n*2+3;i++) fa[i]=i;
char sta;
int x,y;
for(int i=1;i<=m;i++){
cin>>sta>>x>>y;
if(sta=='E'){
fa[fnd(y)]=fnd(x+n);
fa[fnd(y+n)]=fnd(x);
}else{
fa[fnd(x)]=fnd(y);
}
}
for(int i=1;i<=n;i++){
vis[fnd(i)]=true;
}
int cnt=0;
for(int i=1;i<=n*2;i++){
if(vis[i]) cnt++;
}
cout<<cnt;
return 0;
}
PS:最后处理联通块计数也很好。。
[LUOGU] 1892 团伙的更多相关文章
- Luogu P1892 团伙
Luogu P1892 团伙 这是道很简单的并查集-- 不,它并不简单. 这道题考了一个叫做反集的东西. 也就是说: 如果$a$和$b$是敌人,合并$n+b$和$a$,$n+a$和$b$: 如果$c$ ...
- BZOJ 1370: [Baltic2003]Gang团伙(luogu 1892)(种类并查集)
题面: bzoj题面有误,还是看luogu的吧 https://www.luogu.org/problemnew/show/P1892 题解: 种类并查集.. 因为有敌人的敌人是朋友这个条件,所以需要 ...
- 【Luogu P2024&P1892】食物链&团伙(并查集拓展域)
Luogu P1892 Luogu P2024 这两道一眼看过去很容易发现可以用并查集来做--但是当我们仔细阅读题面后,会发现其实并没有那么简单. 我们知道并查集可以很轻松地维护具有传递性的信息,也就 ...
- Luogu P1892 P1525 团伙 关押罪犯
(怎么都是抓罪犯 怪不得写法差不多) 团伙 关押罪犯 并查集.以"敌人的敌人是朋友"的思路来处理.所以增加一个e/E数组来存储敌人. 关押罪犯还用到了贪心的思路.将冲突值从大到小排 ...
- Luogu P1195/P1892 口袋的天空/BOI团伙 【最小生成树/并查集】By cellur925
其实这俩题挺水的,团伙拿下了一血,但是感觉还是写一下博客比较好x. 一.团伙 题目描述 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是 ...
- Luogu P1892 [BOI2003]团伙
P1892 [BOI2003]团伙 题目描述 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的朋友是我的朋友: 我敌人的敌人 ...
- code vs 2597 团伙
题目描述 Description 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的朋友是我的朋友: 我敌人的敌人也是我的朋友 ...
- 洛谷 P1892 [BOI2003]团伙(并查集)
嗯... 题目链接:https://www.luogu.org/problemnew/show/P1892 通过读题可以很清楚的发现这是一个并查集的题,并且要有两个集合: 若他们p和q是朋友,则存入第 ...
- codevs 2597 团伙
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么 ...
随机推荐
- 【Luogu P1502】 窗口的星星
→传送窗口 (复制一下题面好了~) 题目背景 小卡买到了一套新房子,他十分的高兴,在房间里转来转去. 题目描述 晚上,小卡从阳台望出去,“哇~~~~好多星星啊”,但他还没给其他房间设一个窗户,天真的小 ...
- python的pip管理工具
Python有两个著名的包管理工具easy_install.py和pip.在Python2.7的安装包中,easy_install.py是默认安装的,而pip需要我们手动安装. 在此进行编译安装pip ...
- Unrecogized font family ‘Ionicons’ 在ios上报错,android正常
解决方法: react-native link react-native-vector-icons 很多模块都需要link一下
- python 基础(五) 迭代器与生成器
迭代器和生成器 迭代器 iterator (1) 迭代对象: 可以直接作用于for循环的 称为可迭代对象(iterable)可以通过 isinstance 判断是否属于可迭代对象 可以直接作用于for ...
- how browser handler file:/// link
1. why browser can only open .txt file directly, pop up open or save dialog for others? 2. html cann ...
- 转:php中的匿名函数和闭包(closure)
一:匿名函数 (在php5.3.0 或以上才能使用) php中的匿名函数(Anonymous functions), 也叫闭包函数(closures), 允许指定一个没有名称的函数.最常用的就是回调函 ...
- python+selenium问题随记
1.用PhantomJS跑程序,莫名遇到有些元素的text不能读取,后来发现,PhantomJS运行时也需要最大化,不是全屏模式的话也和界面浏览器一样会造成压盖无法读取信息,开始以为是PhantomJ ...
- web基础笔记
浏览器渲染页面的过程 浏览器渲染页面前需要先构建 DOM 和 CSSOM 树.因此,我们需要确保尽快将 HTML 和 CSS 都提供给浏览器. 参考:https://developers.google ...
- Memcached 未授权访问漏洞及加固
memcached是一套分布式的高速缓存系统.它以Key-Value(键值对)形式将数据存储在内存中,这些数据通常是应用读取频繁的.正因为内存中数据的读取远远大于硬盘,因此可以用来加速应用的访问. 漏 ...
- P1816 忠诚 倍增
链接:https://www.luogu.org/problem/show?pid=1816 题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k ...