可以用vis[h][val] = k做;
用vis[h][val] = k;来压缩大于32的部分,保留h= n/32; n为集合编号
当然也可以直接用bitset做;
vis[h][val] = k 压缩的代码如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
//这道题的点就是用位运算做了一个状态压缩,因为int型的数字只有32,而题目中给出的n的范围为1000
//所以要进行压缩,把大于32的部分用一个整数表示,小于32的部分用每一位上是否等于一来判断h* +k是否曾经存在过
int vis[50][10005];
int main()
{
int t;
scanf("%d",&t);
int n,tmp,h,k,maxx;
for(int i=0;i<t;i++)
{
scanf("%d",&n);
while(n--)
{
scanf("%d",&tmp);
int num = i;
h = num/32,k = num%32;
vis[h][tmp] = vis[h][tmp] | (1<<k);
}
}
int Q;
scanf("%d",&Q);
for(int i=0;i<Q;i++)
{
int a,b;
scanf("%d%d",&a,&b);
int flag = 0;
for(int j=0;j<32;j++)
{
if(vis[j][a] & vis[j][b])
{
flag = 1;
break;
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
}
bitset直接做的代码:
bitset 容器使用方法
http://blog.csdn.net/u010480899/article/details/52331363
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string.h>
#include <bitset>
using namespace std;
bitset<1001>s[N];
int main()
{
int n,q,i,j,m,a,b;
scanf("%d",&n);
for(i=0;i<N;i++)
s[i].reset();
for(i=0;i<n;i++)
{
scanf("%d",&m);
for(j=1;j<=m;j++)
{
scanf("%d",&a);
s[a].set(i);
}
}
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&a,&b);
bitset<1001>h=s[a]&s[b];
if(h.count())
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
网友评论