题目
You are given N sets, the i-th set (represent by S(i)) have C(i) element (Here “set” isn’t entirely the same as the “set” defined in mathematics, and a set may contain two same element). Every element in a set is represented by a positive number from 1 to 10000. Now there are some queries need to answer. A query is to determine whether two given elements i and j belong to at least one set at the same time. In another word, you should determine if there exist a number k ( 1 ≤ k ≤ N ) k (1\le k \le N) k(1≤k≤N) such that element i belongs to S(k) and element j also belong to S(k).
题目大意
给定n个集合,然后给出两个数据,判断是否至少有一个集合同时包含这两个数据。
input
First line of input contains an integer N ( 1 ≤ N ≤ 1000 ) N (1 \le N \le 1000) N(1≤N≤1000), which represents the amount of sets. Then follow N lines. Each starts with a number C(i) ( 1 ≤ C ( i ) ≤ 10000 ) (1 \le C(i) \le 10000) (1≤C(i)≤10000), and then C(i) numbers, which are separated with a space, follow to give the element in the set (these C(i) numbers needn’t be different from each other). The N + 2 line contains a number Q ( 1 ≤ Q ≤ 200000 ) (1 \le Q \le 200000) (1≤Q≤200000), representing the number of queries. Then follow Q lines. Each contains a pair of number i and j ( 1 ≤ i , j ≤ 10000 , a n d i m a y e q u a l t o j ) (1 \le i, j \le 10000, and i may equal to j) (1≤i,j≤10000,andimayequaltoj), which describe the elements need to be answer.
output
For each query, in a single line, if there exist such a number k, print “Yes”; otherwise print “No”.
Sample input
3
3 1 2 3
3 1 2 5
1 10
4
1 3
1 5
3 5
1 10
Sample output
Yes
Yes
No
No
分析
首先,因为集合数目最大为1000,每个集合中元素最多为10000,应对规模为200000的查询,采用set对每个集合进行处理并判定,必然会导致超时。但是因为数据的规模在10000以下,可以尝试建立一个二维数组,若是在
i
i
i集合中有
j
j
j,则可以将
a
[
i
]
[
j
]
a[i][j]
a[i][j]置为1,在判断时,若两个数据在同一行中对应位置为1,则说明在同一个集合中。
但是对于数组而言,不论用int还是bool都开不出
1000
×
10000
1000\times10000
1000×10000大小的空间。由此我们可以使用bitset位图进行压位处理。
bitset是一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1位(bit)。当输入一个数的时候,对该数的对应下标采用set()函数置为1。
本题解题时,以每一列表示一个集合,每一行表示该数据是否在某一个集合中。那么,对两个需要检验的数据所在行进行按位&操作,若最后的结果不全为零,即可说明两个数据至少在一个集合中同时出现过。
代码
#include<iostream>
#include<bitset>
using namespace std;
int main(){
bitset<1001> sets[10000];//建立二维数组
int n,c,q,a,b,m;
scanf("%d",&n);
for(int i = 0;i<n;++i){
scanf("%d",&c);
for(int j = 0;j<c;++j){
scanf("%d",&m);
sets[m].set(i);//数据m出现在集合i中
}
}
scanf("%d",&q);
for(int i = 0;i<q;++i){
scanf("%d %d",&a,&b);
bool flag = false;
if((sets[a]&sets[b]).any())//判断是否还有1的存在
printf("Yes\n");
else printf("No\n");
}
return 0;
}