程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> DancingLinks[HUST_1017]

DancingLinks[HUST_1017]

編輯:C++入門知識

因為輸出少了個\n WA了半天。 而且以下兩種寫法效率不一樣。  有待研究 DancingLinks用於優化搜索,核心在於resume操作,可以快速恢復被刪除的結點 1. 1468ms [cpp]   /*http://acm.hust.edu.cn/problem.php?id=1017*/   /*DLX*/   #include<iostream>   #include<cstdio>   #include<cstdlib>   #include<cstring>   using namespace std;   const int MAXN = 200000;   const int MAXM = 1111;   struct DLX{       int L[MAXN],R[MAXN],U[MAXN],D[MAXN],C[MAXN],Col[MAXN],Row[MAXN];       int S[MAXM],Ans[MAXM];       int tot,len;       void build(int N,int M){           memset(S,0,MAXM*sizeof(int));           //construct the head and col head           for(int i=0;i<=M;i++){               U[i] = D[i] = i;               L[i] = i-1;               R[i] = i+1;               C[i] = i;           }           L[0] = M, R[M] = 0; tot = M;           for(int i=1;i<=N;i++){               int K,T; scanf("%d",&K);               for(int j=1;j<=K;j++){                   scanf("%d",&T);                   int node = ++tot;                   C[node] = Col[node] = T;                   Row[node] = i;                   S[T]++;//維護列鏈表節點數                   //維護UD兩個指針                   D[node] = D[C[T]];                   D[C[T]] = node;                   U[D[node]] = node;                   U[D[C[T]]] = C[T];                   C[T] = node; //更新到尾                   //維護LR兩個指針                   if(j==1) L[node] = node+K-1;                   else L[node] = node-1;                   if(j==K) R[node] = node-K+1;                   else R[node] = node+1;               }           }           for(int i=1;i<=M;i++){               C[i] = i;           }//還原列頭指針       }       void debug(){           for(int i=R[0];i!=0;i=R[i]){               printf("C%d: ",i); int r = 1;               for(int j=D[i];j!=i;j=D[j]){                   int ri = Row[j]; //cout<<"ri "<<ri<<" "<<r<<endl;                   while(ri>r){                       r++; printf("0 ");                   }                   printf("1 "); r++;                   //printf("j: %d\n",j);                   //system("pause");               }               printf("\n");           }       }       void remove(const int &c){           L[R[c]] = L[c];           R[L[c]] = R[c];           for(int i=D[c];i!=c;i=D[i]){               for(int j=R[i];j!=i;j=R[j]){                   U[D[j]] = U[j];                   D[U[j]] = D[j];                   S[C[j]]--;               }           }       }       void resume(const int &c){           L[R[c]] = c;           R[L[c]] = c;           for(int i=D[c];i!=c;i=D[i]){               for(int j=R[i];j!=i;j=R[j]){                   U[D[j]] = j;                   D[U[j]] = j;                   S[C[j]]++;               }           }       }       bool dfs(const int &k){           if(R[0]==0){               len = k;               return true;           }           int s(0x7fffffff),c;           for(int i=R[0];i!=0;i=R[i]){               if(S[i]<s){                   c = i;                   s = S[i];               }           }           remove(c);           for(int i=D[c];i!=c;i=D[i]){               Ans[k] = Row[i];               for(int j=R[i];j!=i;j=R[j]){                   remove(C[j]);               }               if(dfs(k+1)){                   return true;               }               for(int j=R[i];j!=i;j=R[j]){                   resume(C[j]);               }           }           resume(c);           return false;       }       void solve(){           if(dfs(0)){               printf("%d",len);               for(int i=0;i<len;i++){                   printf(" %d",Ans[i]);               }               puts("");           }else{               puts("NO");           }       }   }dlx;   int main(){       int N,M;       while(~scanf("%d%d",&N,&M)){           dlx.build(N,M);           dlx.solve();       }       return 0;   }     2.328ms [cpp]   /*http://acm.hust.edu.cn/problem.php?id=1017*/   /*DLX*/   #include<iostream>   #include<cstdio>   #include<cstdlib>   #include<cstring>   using namespace std;   const int MAXN = 2000000;   const int MAXM = 1111;   struct DLX{       int L[MAXN],R[MAXN],U[MAXN],D[MAXN],C[MAXN],Col[MAXN],Row[MAXN];       int S[MAXM],Ans[MAXM];       int tot,len;       void build(int N,int M){           memset(S,0,MAXM*sizeof(int));           //construct the head and col head           for(int i=0;i<=M;i++){               U[i] = D[i] = i;               L[i] = i-1;               R[i] = i+1;               C[i] = i;           }           L[0] = M, R[M] = 0; tot = M;           for(int i=1;i<=N;i++){               int K,T; scanf("%d",&K);               for(int j=1;j<=K;j++){                   scanf("%d",&T);                   int node = ++tot;                   C[node] = Col[node] = T;                   Row[node] = i;                   S[T]++;//維護列鏈表節點數                   //維護UD兩個指針                   D[node] = D[C[T]];                   D[C[T]] = node;                   U[D[node]] = node;                   U[D[C[T]]] = C[T];                   C[T] = node; //更新到尾                   //維護LR兩個指針                   if(j==1) L[node] = node+K-1;                   else L[node] = node-1;                   if(j==K) R[node] = node-K+1;                   else R[node] = node+1;               }           }           for(int i=1;i<=M;i++){               C[i] = i;           }//還原列頭指針       }       void debug(){           for(int i=R[0];i!=0;i=R[i]){               printf("C%d: ",i); int r = 1;               for(int j=D[i];j!=i;j=D[j]){                   int ri = Row[j]; //cout<<"ri "<<ri<<" "<<r<<endl;                   while(ri>r){                       r++; printf("0 ");                   }                   printf("1 "); r++;                   //printf("j: %d\n",j);                   //system("pause");               }               printf("\n");           }       }       void remove(const int &c){           L[R[c]] = L[c];           R[L[c]] = R[c];           for(int i=D[c];i!=c;i=D[i]){               for(int j=R[i];j!=i;j=R[j]){                   U[D[j]] = U[j];                   D[U[j]] = D[j];                   S[C[j]]--;               }           }       }       void resume(const int &c){           for(int i=U[c];i!=c;i=U[i]){               for(int j=L[i];j!=i;j=L[j]){                   U[D[j]] = j;                   D[U[j]] = j;                   S[C[j]]++;               }           }           L[R[c]] = c;           R[L[c]] = c;       }       bool dfs(const int &k){           if(R[0]==0){               len = k;               return true;           }           int s(0x7fffffff),c;           for(int i=R[0];i!=0;i=R[i]){               if(S[i]<s){                   c = i;                   s = S[i];               }           }           remove(c);           for(int i=D[c];i!=c;i=D[i]){               Ans[k] = Row[i];               for(int j=R[i];j!=i;j=R[j]){                   remove(C[j]);               }               if(dfs(k+1)){                   return true;               }               for(int j=L[i];j!=i;j=L[j]){                   resume(C[j]);               }           }           resume(c);           return false;       }       void solve(){           if(dfs(0)){               printf("%d",len);               for(int i=0;i<len;i++){                   printf(" %d",Ans[i]);               }               puts("");           }else{               puts("NO");           }       }   }dlx;   int main(){       int N,M;  www.2cto.com     while(scanf("%d%d",&N,&M)!=EOF){           dlx.build(N,M);           dlx.solve();       }       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved