POJ2443
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 2679 | Accepted: 1050 |
Description
Input
Output
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
Hint
Source
主要是简单的状态压缩,因为数字最大就是10000,而int最大是32位不到,所以分割成10000/30个,分成40份好了。
之后进行状态压缩,神奇的二进制啊。
经过这种处理后,插入是常数,而判断一个数是否在某一个集合也是常数时间。所以每一个查询判断他是否在集合中也就是O(n)。
典型的空间换时间。
一开始我开了一个1000*10000的数组。memset斗可以导致TLE了。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct st{
int u[400];
void add(int n){
int i=n/30,j=n%30;
u[i]|=(1<<j);
}
bool in(int n){
int i=n/30,j=n%30;
return u[i]&(1<<j);
}
void del(int n){
int i=n/30,j=n%30;
u[i]&=~(1<<j);
}
void init(){
memset(u,0,sizeof(u));
}
};
st v[1001];
int main()
{
int n,m,i,s,t;
while(scanf("%d",&n)!=EOF){
for(i=0;i<n;i++){
v[i].init();
scanf("%d",&m);
while(m--){
scanf("%d",&s);
v[i].add(s);
}
}
scanf("%d",&m);
while(m--){
scanf("%d%d",&s,&t);
for(i=0;i<n;i++){
if(v[i].in(s)&&v[i].in(t)){
break;
}
}
if(i==n){
puts("No");
}else{
puts("Yes");
}
}
}
return 0;
}原文地址:http://blog.csdn.net/dengyaolongacmblog/article/details/39993261