题目链接:http://poj.org/problem?id=1703

题意:有n个人分别属于两个团伙,接下来m组形如 ch, x, y的数据,ch为“D"表示 x, y属于不同的团伙,ch为"A"表示询问x,y书否属于同一个团伙;

解法1:我们可以用jion(x, y)属于同一个团伙,jion(x+n, y)表示x属于第二个团伙,y属于第一个团伙,jion(x, y+n)表示x属于第一个团伙,y属于第二个团伙;

那么对于每组不同团伙的x, y我们只需要jion(x+n, y) ,jion(x, y+n)即可;查询时判断x,y或者x+n, y+n根节点是否相同即可,因为集合关系jion表示属于同一团伙,根节点相同则属于相同团伙,若x, y+n,或者x+n, y根节点相同则属于不同团伙,其余情况即为不能确定;

代码:

 #include <iostream>
#include <cstdio>
#include <cstring>
#define MAXN (100000+10) //***MAXN后面做下标时MAXN*2,要加括号,不然会越界!!run time error!!!
using namespace std; int pre[MAXN*], rank[MAXN*]; //***rank用来区分树的高度,但其不存储树的具体高度 int find(int x){
int r = x;
while(pre[r]!=r){
r = pre[r];
}
int i = x; //****路径压缩
while(pre[i]!=r){
int gg = pre[i];
pre[i] = r;
i = gg;
}
return r;
} void jion(int x, int y){
int xx = find(x);
int yy = find(y);
if(rank[xx]>rank[yy]){ //***启发式合并,就是把矮的树合并到高的树地下,把合并时间从0(n)降到o(logn)
pre[yy] = xx;
}else{
pre[xx] = yy;
if(rank[xx] == rank[yy]){ //**若树的标记高度一样,那么给合并后作为父亲的树rank+1,以区分树的高度
rank[xx]++;
}
}
} int main(void){
int t;
scanf("%d", &t);
while(t--){
int n, m;
scanf("%d%d", &n, &m);
for(int i=; i<=*n; i++){
pre[i] = i;
rank[i] = ;
}
while(m--){
char ch[];
int x, y;
scanf("%s%d%d", ch, &x, &y);
if(ch[]=='D'){
jion(x, y+n);
jion(x+n, y);
}else{
if(find(y+n)==find(x)||find(x+n)==find(y)){
printf("In different gangs.\n");
}else if(find(x)==find(y)||find(x+n)==find(y+n)){
printf("In the same gang.\n");
}else{
printf("Not sure yet.\n");
}
}
}
}
return ;
}

方法2:用vis数组标记不同的集合,如:vis[x]=y,表示与x不同集合的点y;

用并查集合并属于同一类的点集;

代码:

 #include <iostream>
#include <stdio.h>
#define MAXN 100010
using namespace std; int pre[MAXN], vis[MAXN], rank[MAXN]; //***vis标记不同集合的编号,rank区分树高
//***vis[x]=y,表示记录x与y不同集合,相当于无向图,所以需双向标记 /*int find(int x){ //**400+ms
int r = x;
while(pre[r]!=r){
r = pre[r];
}
int i = x;
while(i!=r){
int gg = pre[i];
pre[i] = r;
i = gg;
}
return r;
}*/ int find(int x){ //**306ms (再加启发式合并=282ms)
return pre[x]==x ? x : pre[x] = find(pre[x]);
} void jion(int x, int y){
int xx = find(x);
int yy = find(y);
if(rank[xx] > rank[yy]){
pre[yy] = xx;
}else{
pre[xx] = yy;
if(rank[xx] == rank[yy]){
rank[yy]++;
}
}
} int main(void){
int t;
scanf("%d", &t);
while(t--){
int n, m;
scanf("%d%d", &n, &m);
for(int i=; i<=n; i++){
pre[i] = i;
vis[i] = ;
rank[i] = ;
}
while(m--){
char ch[];
int x, y;
scanf("%s%d%d", ch, &x, &y);
if(ch[]=='D'){
if(vis[x]== && vis[y]==){ //**x, y都没出现过
vis[x] = y;
vis[y] = x;
}else if(vis[x]==){ //**x没出现过
vis[x] = y;
jion(x, vis[y]);
}else if(vis[y]==){ //**y没出现过
vis[y] = x;
jion(y, vis[x]);
}else{ //**都出现过
jion(x, vis[y]);
jion(y, vis[x]);
}
}else{
if(find(x)==find(y)){
printf("In the same gang.\n");
}else if(find(x)==find(vis[y])){
printf("In different gangs.\n");
}else{
printf("Not sure yet.\n");
}
}
}
}
return ;
}

方法3:

种类并查集,先区分能不能辨别的情况,然后只要考虑同和不同两种情况,可以用rank数组记录当前节点x与其根节点是否相同的信息,1表相同,0表不同;

代码:

 #include <iostream>
#include <stdio.h>
#define MAXN 100010
using namespace std; int pre[MAXN], rank[MAXN]; //**rank储存x与x的根节点是否相同的信息,1表相同,0表不同 int find(int x){
if(x==pre[x]){
return pre[x];
}
int xx = pre[x];
pre[x] = find(pre[x]);
rank[x] = (rank[x] + rank[xx])&; //**压缩路径,x的根节点改变了,rank[x]也要改变
return pre[x];
} void jion(int x, int y){
int xx = find(x);
int yy = find(y);
if(xx!=yy){
pre[yy] = xx;
rank[yy] = (rank[x] + rank[y] + )&; //**合并只需改变yy之前的rank值
}
} int main(void){
int t;
scanf("%d", &t);
while(t--){
int n, m;
scanf("%d%d", &n, &m);
for(int i=; i<=n; i++){
pre[i] = i;
rank[i] = ;
}
while(m--){
char ch[];
int x, y;
scanf("%s%d%d", ch, &x, &y);
if(ch[]=='D'){
jion(x, y);
}else{
if(find(x)==find(y)){
if(rank[x]==rank[y]){
printf("In the same gang.\n");
}else{
printf("In different gangs.\n");
}
}else{
printf("Not sure yet.\n");
}
}
}
}
return ;
}

poj1703(各种姿势)的更多相关文章

  1. 内网劫持渗透新姿势:MITMf简要指南

    声明:本文具有一定攻击性,仅作为技术交流和安全教学之用,不要用在除了搭建环境之外的环境. 0×01 题记 又是一年十月一,想到小伙伴们都纷纷出门旅游,皆有美酒佳人相伴,想到这里,不禁潸然泪下.子曰:& ...

  2. 判断是否为gif/png图片的正确姿势

    判断是否为gif/png图片的正确姿势 1.在能取到图片后缀的前提下 1 2 3 4 5 6 7 8 9 //假设这是一个网络获取的URL NSString *path = @"http:/ ...

  3. 在Linux(ubuntu server)上面安装NodeJS的正确姿势

    上一篇文章,我介绍了 在Windows中安装NodeJS的正确姿势,这一篇,我们继续来看一下在Linux上面安装和配置NodeJS. 为了保持一致,这里也列举三个方法 第一个方法:通过官网下载安装 h ...

  4. 聊聊 Web 项目二维码生成的最佳姿势

    在设计和实现的过程之后,你永远不知道部署上去的程序会已什么样的姿势运行. 本篇借一次生成二维码逻辑的不同实现,阐述 Web 项目中二维码生成的正确姿势. 文中如有批量,欢迎各位看客老爷拍砖.试运行前5 ...

  5. Lua手动编译姿势

    LUA-5.3.3.tar.gz Lua源码+链接2016年5月30日更新 手动编译姿势: 已经装有VS2010 使用VS自带的 cl.exe以及 VS命令簿 打开文件地址 运行自己的bat文件 my ...

  6. 浅谈OC对象初始化的三种姿势

    一.普通程序猿普通程序员使用最常见路人姿势等场.普普通通,纯属陆仁辈. 陆仁贾写法: // view 1 UIView *v1 = [UIView alloc] initWithFrame:CGRec ...

  7. 与MySQL传统复制相比,GTID有哪些独特的复制姿势?

    与MySQL传统复制相比,GTID有哪些独特的复制姿势? http://mp.weixin.qq.com/s/IF1Pld-wGW0q2NiBjMXwfg 陈华军,苏宁云商IT总部资深技术经理,从事数 ...

  8. 快速了解IOC的几种姿势

    一.首先我们了解IOC如何注入的几种姿势 构造函数注入(Constructor Injection) Ioc容器会智能的选择和调用合适的构造函数以创建依赖的对象.如果被选择的构造函数具有相应的参数,I ...

  9. xpath轴的正确使用姿势

    网上看了许多关于轴的介绍,只介绍了语法,而没有明说具体实际中该怎么使用,百思不得其解. 背景--python中使用xpath:  ----------------------------------- ...

随机推荐

  1. zabbix 3.0.4 监控windows 服务

    下载客户端 http://www.zabbix.com/download.php http://www.zabbix.com/downloads/3.0.4/zabbix_agents_3.0.4.w ...

  2. 优雅地使用Windows

    优雅地使用Windows 理财推荐:收益还行,安全性比余额宝高,只能自己的卡转进转出所以被盗也不怕,重要的是快速取现实时到账呢 1 现金宝 :点击进入现金宝 或者百度现金宝 2 百度理财 8.baid ...

  3. sass兼容IE8透明度方法

    你可以轻松的利用 {Sass::Script::Functions#ie_hex_str ie_hex_str} 函数对其做转换.$translucent-red: rgba(, , , 0.5); ...

  4. git中的版本库,暂存区和工作区

  5. ES6中Arguments和Parameters用法解析

    原文链接 译文 ECMAScript 6 (也称 ECMAScript 2015) 是ECMAScript 标准的最新版本,显著地完善了JS中参数的处理方式.除了其它新特性外,我们还可以使用rest参 ...

  6. 好无语的问题----include 后面需要空格么?

    前俩天回学校办事,在去师弟宿舍的时候,被问到了一个很 "深奥"得问题 ---------include  后面需要空格么? 在我以前的印象中不管在哪个编译器中,,都是需要有空格的, ...

  7. JavaScript深入浅出4-对象

    慕课网教程视频地址:Javascript深入浅出 对象的结构:包含一系列无序的属性,每个属性都有字符串key和对应的值 创建对象:对象字面量.new/原型链.Object.create 对象的属性操作 ...

  8. LED notification in Android device

    Code can control the LED notification in Android device, using android.app.Notification: 1 2 3 4 5 6 ...

  9. 4 Handler相关类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. Handler相关类概述 处理程序相关类一共有三个,其没有派生继承关系,但是其有友元关系和使用关系 ...

  10. c# winform UI + python底层的一点尝试

    鉴于python做winform之类的UI比较弱.于是想结合C#的winform 和 python的底层开发(windows平台). 尝试做了一个RSS阅读器.在这里:http://download. ...