种类并查集
来源:互联网 发布:公文写作神器软件 编辑:程序博客网 时间:2024/05/17 08:25
HDU 1829 A Bug's Life
这是今天写的第三道并查集,有了前面两道的铺垫,写这一道很快就写完了,网上博客说说这是水题.............暴风哭泣,好吧不管我还是很开心的
题目大体意思就是额? 输入一对x,y表示的是异性关系,而在处理这个关系之前看下是否是同性关系,如果是同性关系的话,那么就是错的 大体就是这样子了
然后嗯 因为不确定每个人到底是女的还是男的所以其实是有两种可能的
那么我们就是设置pre【】为n最大的两倍 之后每次要处理的时候判断下 是否是同性 如果是那么就错了
emmm 理解的关键可能在于有几种可能性,这是我觉得种类并查集理解最最最最关键的一步,我暑假的时候写这个死都不理解。因为根据每种可能性去处理可能发生的事情大体就是这个样子
代码如下:
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;const int maxn=4020;int pre[maxn]; int n,m;void init(){for(int i=1;i<=2*n;i++)pre[i]=i;}int ufind(int k) { if(k==pre[k]) return k; return pre[k]=ufind(pre[k]);} void merge(int x,int y){int fx=ufind(x);int fy=ufind(y);if(fx!=fy)pre[fx]=fy;}bool same(int a, int b) { return ufind(a) == ufind(b); } int main(){int t,x,y;scanf("%d",&t);for(int u=1;u<=t;u++){scanf("%d%d",&n,&m);init();int flag=0;while(m--){scanf("%d%d",&x,&y);if(flag)continue;if(same(x,y)||same(x+n,y+n))flag=1; merge(x,y+n);merge(x+n,y);}printf("Scenario #%d:\n",u);if(flag)printf("Suspicious bugs found!\n");else printf("No suspicious bugs found!\n");putchar('\n');}return 0;}
POJ - 1182
B - 食物链
这题是写种类并查集的第一题,真的特别痛苦记得暑假就做过了,当时也理解得不够透彻后来每次出现种类自己也都不愿意去写这种题目
然后就是开三个数组
0----N-1表示的是在A组 N----2N-1表示的是在B组 2N----3N-1表示得是在C组
因为不确定这个动物到底是在哪一组所以每种情况都是要考虑
当输入的为1的 我们要判断是否是吃与被吃的关系 其实算是
if(same(x,y+n)||same(x,y+2*n))刚刚尝试了下把
if(same(y,x+n)||same(y,x+2*n))调换过来也是ok的嗯~~~~ 就是当x是A判断一下他是否是B或者是C
当输入的为2的时候 我们要判断是否是相同的关系或者是被吃的关系
代码:
/*假设A为0----N-1 则B为N---2N-1 C为2N----3N-1; A吃B, B吃C,C吃A。*/ #include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;int pre[150015]; int n;void init(){for(int i=0;i<=3*n;i++)pre[i]=i;} int find(int a) { int x=a; while(pre[x]!=x) { x=pre[x]; } return x; } bool same(int n,int m) { return find(n)==find(m); } void merge(int x,int y) { int f1=find(x); int f2=find(y); if(f1!=f2) pre[f1]=f2; } int main(){int k,choice,x,y;scanf("%d%d",&n,&k);int ans=0;init();while(k--){scanf("%d%d%d",&choice,&x,&y);if(x>n||y>n||x<1||y<1){ans++;continue;}x=x-1;y=y-1;if(choice==1) //表示同类 所以要先判断他们是x吃y或者是y吃x的关系 {if(same(x,y+n)||same(x,y+2*n))ans++;else {merge(x,y);merge(x+n,y+n);merge(x+2*n,y+2*n);} }else if(choice==2) // 这个要表示的是x吃y 先判断是不是同类 或者说 y吃x {if(same(x,y)||same(x,y+2*n))ans++;else {merge(x,y+n);merge(x+n,y+2*n);merge(x+2*n,y);}}}printf("%d\n",ans);return 0;}
C - Find them, Catch them
POJ - 1703emmm就是判断他是否在相同的团伙中和第一个性别的那个是一个意思的都一样的思路
代码:
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;const int maxn=2*1e5+10; int pre[maxn]; int n,m;int ufind(int k) { if(k==pre[k]) return k; return pre[k]=ufind(pre[k]);} void merge(int x,int y){int fx=ufind(x);int fy=ufind(y);if(fx!=fy)pre[fx]=fy;}bool same(int a, int b) { return ufind(a) == ufind(b); } int main(){int t,x,y;char str[10];scanf("%d",&t);while(t--){scanf("%d%d",&n,&m); for(int i=0;i<=2*n;i++) pre[i]=i;while(m--){scanf(" %s%d%d",str,&x,&y);if(str[0]=='D'){merge(x,n+y);merge(n+x,y);}else if(str[0]=='A'){if(same(x,n+y))printf("In different gangs.\n");else if(same(x,y))printf("In the same gang.\n");else printf("Not sure yet.\n");}}}return 0;}
阅读全文
0 0
- 种类并查集
- 种类并查集
- 种类并查集
- 种类并查集
- 种类并查集
- 种类并查集
- poj1182 种类并查集
- poj1182 种类并查集
- poj1703 种类并查集
- 食物链 种类并查集
- POJ2492(种类并查集)
- 种类并查集小结
- p1403 种类并查集
- 食物链----种类并查集
- ACM_种类并查集
- 食物链 种类并查集
- 种类并查集讲解
- POJ1182【种类并查集】
- java基础2:异常
- ADS7822的使用
- this逃逸
- 文件的存取
- 一致性哈希算法
- 种类并查集
- Scrapy-redis增量爬取以及Simhash相似文档的去重
- 【基础】队列的插入和删除--C++源代码(g++ 7.2.0)
- 轻松搭建 VPS ($2.5/月 支付宝)
- Nginx是什么能干什么,linux安装
- 关于Python利用爬虫给朋友讲笑话
- Android画廊实现一滴雨及多滴雨
- 新Mac配置python,以及虚拟环境
- u-boot 2013.04-rc1移植(2)