洛谷1892 团伙
来源:互联网 发布:avdb新域名 编辑:程序博客网 时间:2024/05/16 10:45
题目描述
1920年的芝加哥,出现了一群强盗。如果两个强盗遇上了,那么他们要么是朋友,要么是敌人。而且有一点是肯定的,就是:
我朋友的朋友是我的朋友;
我敌人的敌人也是我的朋友。
两个强盗是同一团伙的条件是当且仅当他们是朋友。现在给你一些关于强盗们的信息,问你最多有多少个强盗团伙。
算法
第一眼看到这道题:诶?这不是并查集裸题吗?
事实也如此,对于朋友直接合并集合就行了,但是对于敌人应该怎么处理呢?
用数组f[i][j]来表示i和j是敌人,在每次输入敌人关系时循环合并即可。
这样这道题就变得十分简单了。
代码
#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>using namespace std;int root[1010]; //并查集 父节点 bool f[1010][1010]; //仇敌关系 int find(int x) //寻找根节点(有路径压缩) { if (root[x]!=x) root[x]=find(root[x]); return root[x];}void merge(int x,int y) //合并集合 { int r1=find(x),r2=find(y); if (r1!=r2) root[r2]=r1;}int main(){ ios::sync_with_stdio(false); //加速cin & cout int n,m; cin>>n>>m; for (int i=1;i<=n;i++) root[i]=i; //初始化 while (m--) { char c; int a,b; cin>>c>>a>>b; if (c=='F') merge(a,b); //朋友就直接合并 else //仇敌关系 { f[a][b]=f[b][a]=true; //先保存 for (int k=1;k<=n;k++) //再循环合并 { if (f[a][k]) merge(b,k); //敌人的敌人是朋友 if (f[b][k]) merge(a,k); //同上 } } } int ans=0; for (int i=1;i<=n;i++) //统计父节点数(也就是团伙数) if (root[i]==i) ans++; printf("%d\n",ans); //输出 return 0;}
后记
一开始作者这只蒟蒻看到仇敌关系也是很懵,但是这道题数据范围较小,所以我使用了这种暴力的方法。
不过这道题当作并查集练手题来做还是很好的!
阅读全文
1 0
- 洛谷1892 团伙
- 【洛谷1892】团伙 并查集
- 洛谷 P1892 团伙
- 洛谷P1892团伙
- 团伙
- 团伙
- 团伙
- 团伙(group)
- 犯罪团伙
- codevs2597团伙
- BZOJ1370Gang团伙
- 【9009】团伙
- 犯罪团伙
- P1892 团伙
- wustoj1939团伙
- [codevs2597]团伙
- bzoj1370 团伙
- rqnoj 577 团伙
- Java实现图片上传到服务器,并把上传的图片读取出来
- js高级程序设计(第三版)第五章
- javascript笔记2017/8/21
- sdkman node npm gradle gulp 学习笔记0818 1.3
- react学习笔记
- 洛谷1892 团伙
- MySQL 行级锁 表级锁
- Leetcode 78. Subsets & 90. Subsets II
- win下Eclipse远程连接Hbase的配置及程序示例(create、insert、get、delete)
- 【linux命令】Centos下如何匹配内容在哪个文件中
- 【Noip2011】计算系数
- python简介(1)
- HDOJ1879 继续畅通工程
- JavaScript的执行环境及作用域