zoukankan      html  css  js  c++  java
  • UVA

    题目链接

    正解是IDA*+四个方向判重,但由于是个裸的可重复覆盖问题,可以用DLX水过~

    每个格子与放上皇后能干掉的标记连边,跑可重复覆盖DLX。注意要用IDA*来优化,否则会超时。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=10+2;
     5 int n,m,np,ka;
     6 char s[N][N];
     7 struct P {int x,y;} p[N*N];
     8 bool ok(P a,P b) {
     9     if(a.x==b.x)return 1;
    10     if(a.y==b.y)return 1;
    11     if(abs(a.x-b.x)==abs(a.y-b.y))return 1;
    12     return 0;
    13 }
    14 
    15 struct DLX {
    16     static const int N=1000;
    17     static const int M=1000;
    18     static const int MX=10000;
    19     int n,tot,S[M],H[N],vis[M];
    20     int row[MX],col[MX],L[MX],R[MX],U[MX],D[MX];
    21     void init(int _n) {
    22         n=_n;
    23         for(int i=0; i<=n; ++i) {
    24             U[i]=D[i]=i;
    25             L[i]=i-1,R[i]=i+1;
    26         }
    27         L[0]=n,R[n]=0;
    28         tot=n+1;
    29         memset(S,0,sizeof S);
    30         memset(H,-1,sizeof H);
    31         memset(vis,0,sizeof vis);
    32     }
    33     void link(int r,int c) {
    34         int u=tot++;
    35         S[c]++;
    36         row[u]=r,col[u]=c;
    37         U[u]=U[c],D[u]=c;
    38         U[D[u]]=D[U[u]]=u;
    39         if(!~H[r])H[r]=L[u]=R[u]=u;
    40         else {
    41             R[u]=H[r],L[u]=L[H[r]];
    42             L[R[u]]=R[L[u]]=u;
    43         }
    44     }
    45     void remove(int c) {
    46         for(int i=D[c]; i!=c; i=D[i])L[R[i]]=L[i],R[L[i]]=R[i];
    47     }
    48     void restore(int c) {
    49         for(int i=U[c]; i!=c; i=U[i])L[R[i]]=R[L[i]]=i;
    50     }
    51     int h() {
    52         int ret=0;
    53         for(int c=R[0]; c!=0; c=R[c])vis[c]=1;
    54         for(int c=R[0]; c!=0; c=R[c])if(vis[c]) {
    55                 ++ret,vis[c]=0;
    56                 for(int i=D[c]; i!=c; i=D[i])
    57                     for(int j=R[i]; j!=i; j=R[j])vis[col[j]]=0;
    58             }
    59         return ret;
    60     }
    61     void check() {
    62         for(int c=1; c<=n; ++c)if(!S[c]) {
    63                 for(int i=D[c]; i!=c; i=D[i])L[R[i]]=L[i],R[L[i]]=R[i];
    64                 L[R[c]]=L[c],R[L[c]]=R[c];
    65             }
    66     }
    67     bool dfs(int dep,int mxd) {
    68         if(R[0]==0)return 1;
    69         if(dep+h()>mxd)return 0;
    70         int c=R[0];
    71         for(int i=R[0]; i!=0; i=R[i])if(S[i]<S[c])c=i;
    72         for(int i=D[c]; i!=c; i=D[i]) {
    73             remove(i);
    74             for(int j=R[i]; j!=i; j=R[j])remove(j);
    75             if(dfs(dep+1,mxd))return 1;
    76             for(int j=L[i]; j!=i; j=L[j])restore(j);
    77             restore(i);
    78         }
    79         return 0;
    80     }
    81     int IDAStar() {for(int mxd=0;; ++mxd) {if(dfs(0,mxd))return mxd;}}
    82 } dlx;
    83 
    84 int main() {
    85     while(scanf("%d%d",&n,&m)&&n) {
    86         np=0;
    87         for(int i=0; i<n; ++i)scanf("%s",s[i]);
    88         for(int i=0; i<n; ++i)
    89             for(int j=0; j<m; ++j)if(s[i][j]=='X')p[np++]= {i,j};
    90         dlx.init(np);
    91         for(int i=0; i<n; ++i)
    92             for(int j=0; j<m; ++j)
    93                 for(int k=0; k<np; ++k)
    94                     if(ok({i,j}, p[k]))dlx.link(i*m+j+1,k+1);
    95         printf("Case %d: %d
    ",++ka,dlx.IDAStar());
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    CodeForces 785D Anton and School
    CodeForces 785C Anton and Fairy Tale
    CodeForces 785B Anton and Classes
    CodeForces 785A Anton and Polyhedrons
    爱奇艺全国高校算法大赛初赛C
    爱奇艺全国高校算法大赛初赛B
    爱奇艺全国高校算法大赛初赛A
    EOJ 3265 七巧板
    EOJ 3256 拼音魔法
    EOJ 3262 黑心啤酒厂
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10375228.html
Copyright © 2011-2022 走看看