• 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 }
  • 相关阅读:
    C#的内存管理原理解析+标准Dispose模式的实现
    深入理解C#:编程技巧总结(二)
    深入理解C#:编程技巧总结(一)
    深刻理解:C#中的委托、事件
    你知道JavaScript中的结果值是什么吗?
    switch语句的妙用
    相等比较、关系比较总结
    用ServiceStack操作使用redis的问题
    springmvc 处理put,delete请求
    easyui 验证动态添加和删除问题
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10375228.html
Copyright © 2020-2023  润新知