POJ--2443(二进制压缩 / bitset)
2015-01-18 15:48:24
思路:用1000*10000的01矩阵来表示数是否存在。
直接用数组显然存不下,那么考虑用30+个int型数去存每一列,以其二进制位来表示0、1,31*33 > 1000,最多用33个整数即可,将时间和空间复杂度将为33 * 10000。
用bitset实现:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <bitset> 10 #include <queue> 11 #include <string> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 #define MEM(a,b) memset(a,b,sizeof(a)) 17 #define REP(i,n) for(int i=1;i<=(n);++i) 18 #define REV(i,n) for(int i=(n);i>=1;--i) 19 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 20 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 21 #define MP(a,b) make_pair(a,b) 22 23 typedef long long ll; 24 typedef pair<int,int> pii; 25 const int INF = (1 << 30) - 1; 26 const int maxn = 10010; 27 28 int N,Q; 29 bitset<1010> b[maxn],judge; 30 31 int main(){ 32 int a,c; 33 while(scanf("%d",&N) != EOF){ 34 REP(i,10000) b[i].reset(); 35 REP(i,N){ 36 scanf("%d",&c); 37 REP(j,c){ 38 scanf("%d",&a); 39 b[a].set(i); 40 } 41 } 42 scanf("%d",&Q); 43 REP(i,Q){ 44 scanf("%d%d",&a,&c); 45 judge = b[a] & b[c]; 46 if(judge.any()) printf("Yes\n"); 47 else printf("No\n"); 48 } 49 } 50 return 0; 51 } 52
用int二进制压缩:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=1;i<=(n);++i) 17 #define REV(i,n) for(int i=(n);i>=1;--i) 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 20 #define MP(a,b) make_pair(a,b) 21 22 typedef long long ll; 23 typedef pair<int,int> pii; 24 const int INF = (1 << 30) - 1; 25 const int maxn = 10010; 26 27 int N,Q; 28 int g[maxn][40]; 29 30 int main(){ 31 int a,c; 32 while(scanf("%d",&N) != EOF){ 33 MEM(g,0); 34 int top = N / 31 + 1; 35 REP(i,N){ 36 scanf("%d",&c); 37 int pos = i / 31; 38 int val = 1 << (i % 31); 39 REP(j,c){ 40 scanf("%d",&a); 41 g[a][pos] |= val; 42 } 43 } 44 scanf("%d",&Q); 45 REP(i,Q){ 46 scanf("%d%d",&a,&c); 47 bool flag = false; 48 FOR(j,0,top) if((g[a][j] & g[c][j]) != 0){ 49 flag = true; 50 break; 51 } 52 if(flag) printf("Yes\n"); 53 else printf("No\n"); 54 } 55 } 56 return 0; 57 } 58