POJ1703 && POJ2942 &&POJ 1182 并查集 这个做法挺巧妙
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 37242 | Accepted: 11483 |
Description
two criminals; do they belong to a same clan? You must give your judgment based on incomplete information. (Since the gangsters are always acting secretly.)
Assume N (N <= 10^5) criminals are currently in Tadu City, numbered from 1 to N. And of course, at least one of them belongs to Gang Dragon, and the same for Gang Snake. You will be given M (M <= 10^5) messages in sequence, which are in the following two kinds:
1. D [a] [b]
where [a] and [b] are the numbers of two criminals, and they belong to different gangs.
2. A [a] [b]
where [a] and [b] are the numbers of two criminals. This requires you to decide whether a and b belong to a same gang.
Input
Output
Sample Input
1
5 5
A 1 2
D 1 2
A 1 2
D 2 4
A 1 4
Sample Output
Not sure yet.
In different gangs.
In the same gang.
题意是在Tadu这个城市有两个团伙。
给出D i j的意思是说i和j不是一个团伙的。
给出A i j的意思是根据已知的信息,能不能确定i和j是一个团伙的,如果确定是一个团伙的,输出“In different gangs.”。如果确定不是一个团伙的,输出“In the same gang.”。如果不能确定,输出“Not sure yet.”
之前使用并查集都是判断两个人是不是在一个集合里,这次要确定地判断两个人不在集合里,所以想法就是添加无用的N个元素作为桥梁。i k不在一个集合中,k j不在一个集合中,说明i j在一个集合中,那我把i k j都放入集合中,只不过k是我查询永远都不会用到的元素,所以就是添加元素时 i k+N,k+N j添加到集合中。所以当我查询k+N,j 发现他们在一个集合中时,就恰恰说明了k和j在两个团伙里面。
代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std; char oper[5];
int n,m,num;
int pre[200015]; int findpre(int x)
{
while(x!=pre[x])
{
x=pre[x];
}
return x;
} void union_set(int x,int y)
{
int pre_x=findpre(x);
int pre_y=findpre(y); if(pre_x == pre_y)
return;
else if(pre_x>pre_y)
{
int temp = pre_x;
pre_x = pre_y;
pre_y = temp;
}
pre[pre_y]=pre_x;
} bool same(int x,int y)
{
return findpre(x) == findpre(y);
} int main()
{
//freopen("i.txt","r",stdin);
//freopen("o.txt","w",stdout); int test,i,temp1,temp2;
scanf("%d",&test); while(test--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=2*n;i++)
{
pre[i]=i;
}
for(i=1;i<=m;i++)
{
scanf("%s%d%d",oper,&temp1,&temp2);
if(oper[0]=='A')
{
if(same(temp1,temp2))
{
printf("In the same gang.\n");
}
else if(same(temp1+n,temp2)||same(temp1,temp2+n))
{
printf("In different gangs.\n");
}
else
{
printf("Not sure yet.\n");
} }
else if(oper[0]=='D')
{
union_set(temp1,temp2+n);
union_set(temp1+n,temp2);
}
}
}
//system("pause");
return 0;
}
POJ2942与此类似,代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std; int n,m;
int pre[200015]; int findpre(int x)
{
while(x!=pre[x])
{
x=pre[x];
}
return x;
} void union_set(int x,int y)
{
int pre_x=findpre(x);
int pre_y=findpre(y); if(pre_x == pre_y)
return;
else if(pre_x>pre_y)
{
int temp = pre_x;
pre_x = pre_y;
pre_y = temp;
}
pre[pre_y]=pre_x;
} bool same(int x,int y)
{
return findpre(x) == findpre(y);
} int main()
{
//freopen("i.txt","r",stdin);
//freopen("o.txt","w",stdout); int test,i,j,temp1,temp2;
scanf("%d",&test); for(i=1;i<=test;i++)
{
printf("Scenario #%d:\n",i);
scanf("%d%d",&n,&m); for(j=1;j<=2*n;j++)
{
pre[j]=j;
} bool flag=false;
for(j=1;j<=m;j++)
{
scanf("%d%d",&temp1,&temp2); if(flag)continue; if(same(temp1,temp2))
{
flag=true;
continue;
}
union_set(temp1,temp2+n);
union_set(temp1+n,temp2);
}
if(flag)
{
printf("Suspicious bugs found!\n\n");
}
else
{
printf("No suspicious bugs found!\n\n");
}
} //system("pause");
return 0;
}
POJ1182是把集合弄成了3个,那与此同理,就是x,x+n,x+2*n的区别,用x,y+n表示A吃B的集合。再对每一个语句进行排除,得到答案。
代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std; int n,m,num;
int pre[150015]; int findpre(int x)
{
while(x!=pre[x])
{
x=pre[x];
}
return x;
} void union_set(int x,int y)
{
int pre_x=findpre(x);
int pre_y=findpre(y); if(pre_x == pre_y)
return;
else if(pre_x>pre_y)
{
int temp = pre_x;
pre_x = pre_y;
pre_y = temp;
}
pre[pre_y]=pre_x;
} bool same(int x,int y)
{
return findpre(x) == findpre(y);
} int main()
{
//freopen("i.txt","r",stdin);
//freopen("o.txt","w",stdout); int oper,i,x,y,ans;
scanf("%d%d",&n,&m); ans=0;
for(i=1;i<=3*n;i++)
{
pre[i]=i;
}
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&oper,&x,&y);
if(x<=0||x>n||y<=0||y>n)
{
ans++;
continue;
}
if(oper==1)
{
if(same(x,y+n)||same(x,y+2*n)||same(x+n,y))
{
ans++;
continue;
}
union_set(x,y);
union_set(x+n,y+n);
union_set(x+2*n,y+2*n);
}
else if(oper==2)
{
if(x==y||same(x,y)||same(x+n,y)||same(x,y+2*n))
{
ans++;
continue;
}
union_set(x,y+n);
union_set(x+n,y+2*n);
union_set(x+2*n,y);
}
}
printf("%d\n",ans);
//system("pause");
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ1703 && POJ2942 &&POJ 1182 并查集 这个做法挺巧妙的更多相关文章
- POJ 1182 并查集
Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...
- 食物链 POJ - 1182 (并查集的两种写法)
这是一个非常经典的带权并查集,有两种写法. 1 边权并查集 规定一下,当x和y这条边的权值为0时,表示x和y是同类,当为1时,表示x吃y,当为2时,表示x被y吃. 一共有三种状态,如图,当A吃B,B吃 ...
- poj 1182 并查集高级应用
C - 是谁站在食物链的顶端 Crawling in process... Crawling failed Time Limit:1000MS Memory Limit:10000KB ...
- poj 1984 并查集
题目意思是一个图中,只有上下左右四个方向的边.给出这样的一些边, 求任意指定的2个节点之间的距离. 就是看不懂,怎么破 /* POJ 1984 并查集 */ #include <stdio.h& ...
- poj 1797(并查集)
http://poj.org/problem?id=1797 题意:就是从第一个城市运货到第n个城市,最多可以一次运多少货. 输入的意思分别为从哪个城市到哪个城市,以及这条路最多可以运多少货物. 思路 ...
- POJ 2492 并查集扩展(判断同性恋问题)
G - A Bug's Life Time Limit:10000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u S ...
- POJ 2492 并查集应用的扩展
A Bug's Life Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 28651 Accepted: 9331 Descri ...
- POJ 3228 [并查集]
题目链接:[http://poj.org/problem?id=3228] 题意:给出n个村庄,每个村庄有金矿和仓库,然后给出m条边连接着这个村子.问题是把所有的金矿都移动到仓库里所要经过的路径的最大 ...
- poj 1733 并查集+hashmap
题意:题目:有一个长度 已知的01串,给出多个条件,[l,r]这个区间中1的个数是奇数还是偶数,问前几个是正确的,没有矛盾 链接:点我 解题思路:hash离散化+并查集 首先我们不考虑离散化:s[x] ...
随机推荐
- How to add VTL tapes on DD6300 & label them into "Oracle_VTL" pool
Dear all , This is liulei , I was back so , How to add VTL tapes on DD6300 & label them into ...
- redhat 7.6 密码破解(无光盘)
开机,在下面界面按e 找到linux16 在最尾输入 rd.break 按 Ctrl+x 输入 mount -o remount,rw /sysroot 输入chroot /sysroot sh ...
- Codeforces 1304C. Air Conditioner
本题直接对每个区间取并,若出现非法区间就是No 否则就是Yes #include<bits/stdc++.h> using namespace std; #define lowbit(x) ...
- Codeforces1300C-Anu Has a Function
定义一个函数f(x,y), f(x,y) = x|y - y,给你一个数列,a1,a2,,an问如何排列能使f(f(f(a1,a2),a3),````,an)答案最大,我们将f(x,y)变形,就是f( ...
- unittest---unittest生成测试报告
我们做测试的人员们都知道测试完成后,肯定是会生成一个测试报告,那么当我们做自动化的时候,这个自动化报告也可以自动生成吗?python当然可以了! HTMLTestRunner HTMLTestRunn ...
- 九 SpringMvc与json交互
将json输出到页面: 1 加入jar包 2 配置Controller层,开启注解ResponseBody,将json发送到页面: 3 访问url 4 响应json,在形参列表里面加上注解
- linux 查看Apache Tomcat日志访问IP前10
访问日志名:localhost_access_log.2019-01-29.txt 日志格式示例 /Nov/::: +] /Nov/::: +] /Nov/::: +] /Nov/::: +] /No ...
- Python中turtle绘图学习笔记和实例
一.既然本次讲的主角是turtle函数库,那肯定得先了解一下它是什么 turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x.纵轴为y的坐标系原点,(0,0)位 ...
- 16核锐龙9延期真正原因 A饭热情太恐怖了
锐龙9 3950X处理器是AMD发布的首款16核游戏处理器,原本会在9月上市,上周末AMD官方宣布它会延期2个月上市,会在11月跟锐龙Threadripper三代处理器一起上市. 锐龙9 3950X的 ...
- Python 3网络爬虫开发实战书籍
Python 3网络爬虫开发实战书籍,教你学会如何用Python 3开发爬虫 本书介绍了如何利用Python 3开发网络爬虫,书中首先介绍了环境配置和基础知识,然后讨论了urllib.reques ...