hdu3335 n个数最多选多少个使所选的数两两不能整除 DLX可重复覆盖
额,感觉建立矩阵好强==
最多选多少个两两不能整除->将可以整除的记为true,这样跑最大可重复覆盖就是最多可以选的数==
看到好多二分图匹配做的,不写了==
1 #include<stdio.h> 2 #include<math.h> 3 #include<string.h> 4 #include<algorithm> 5 #define eps 1e-8 6 #define LL long long 7 using namespace std; 8 struct DLX{ 9 int n,m,size,ansd,ans[1005]; 10 int U[1000005],D[1000005],L[1000005],R[1000005]; 11 int Row[1000005],Col[1000005],H[1005],S[1005]; 12 void init(int _n,int _m){ 13 ansd=0; 14 n=_n; m=_m; 15 for (int i=0;i<=m;i++){ 16 S[i]=0; 17 U[i]=D[i]=i; 18 L[i]=i-1; R[i]=i+1; 19 } 20 R[m]=0; L[0]=m; 21 size=m; 22 for (int i=1;i<=n;i++) H[i]=-1; 23 } 24 void link(int r,int c){ 25 S[c]++; 26 Col[++size]=c; Row[size]=r; 27 D[size]=D[c]; U[D[c]]=size; 28 U[size]=c; D[c]=size; 29 if (H[r]<0) H[r]=L[size]=R[size]=size; 30 else{ 31 R[size]=R[H[r]]; 32 L[R[H[r]]]=size; 33 L[size]=H[r]; 34 R[H[r]]=size; 35 } 36 } 37 void remove(int c){ 38 for (int i=D[c];i!=c;i=D[i]) 39 L[R[i]]=L[i],R[L[i]]=R[i]; 40 } 41 void resume(int c){ 42 for (int i=U[c];i!=c;i=U[i]) 43 L[R[i]]=R[L[i]]=i; 44 } 45 void Dance(int d){ 46 if (R[0]==0) { 47 ansd=max(ansd,d); 48 return; 49 } 50 int c=R[0]; 51 for (int i=R[0];i;i=R[i]) 52 if (S[i]<S[c]) c=i; 53 for (int i=D[c];i!=c;i=D[i]){ 54 remove(i); 55 for (int j=R[i];j!=i;j=R[j]) remove(j); 56 Dance(d+1); 57 for (int j=L[i];j!=i;j=L[j]) resume(j); 58 resume(i); 59 } 60 } 61 }G; 62 LL a[1005]; 63 int main() 64 { 65 int T,i,j,n; 66 scanf("%d",&T); 67 while (T--){ 68 scanf("%d",&n); 69 for (i=1;i<=n;i++) 70 scanf("%I64d",&a[i]); 71 G.init(n,n); 72 for (i=1;i<=n;i++) 73 for (j=1;j<=n;j++) 74 if (a[i]%a[j]==0||a[j]%a[i]==0) G.link(i,j); 75 G.Dance(0); 76 printf("%d\n",G.ansd); 77 } 78 return 0; 79 }