FZU - 1686
Description Input Output Sample Input
4 41 0 0 10 1 1 00 1 1 01 0 0 12 24 4 0 0 0 00 1 1 00 1 1 00 0 0 02 2
Sample Output
41
|
思路:因为要消灭所有的敌人,也就是覆盖矩阵中所有的1,所以多所有的1编号,然后这些当做列,然后每个位置当做行,他有影响的范围,对应1对应的编号的列
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int INF=1000000000;
const int maxn=15*15+10;
const int maxm=15*15+10;
const int maxnode=maxn*maxm;
int N,M,n,m;
int id[20][20];
struct DLX
{
int n,m,size;
int U[maxnode],D[maxnode],R[maxnode],L[maxnode];
int H[maxn],S[maxm];
int row[maxnode],col[maxnode];
int ansd,ans[maxn];
bool vis[maxnode];
void init(int N,int M)
{
n=N,m=M;
ansd=INF;
for(int i=0;i<=m;i++)
{
S[i]=0;
U[i]=D[i]=i;
L[i]=i-1;
R[i]=i+1;
}
L[0]=m,R[m]=0;
size=m;
for(int i=0;i<=n;i++)H[i]=-1;
}
void Link(int r,int c)
{
++S[col[++size]=c];
row[size]=r;
D[size]=D[c];
U[size]=c;
U[D[c]]=size;
D[c]=size;
if(H[r]<0)H[r]=R[size]=L[size]=size;
else
{
R[size]=R[H[r]];
L[size]=H[r];
L[R[H[r]]]=size;
R[H[r]]=size;
}
}
void remove(int c)
{
for(int i=D[c];i!=c;i=D[i])
L[R[i]]=L[i],R[L[i]]=R[i];
}
void restore(int c)
{
for(int i=U[c];i!=c;i=U[i])
L[R[i]]=R[L[i]]=i;
}
int f()
{
int cnt=0;
for(int i=R[0];i;i=R[i])vis[i]=0;
for(int c=R[0];c;c=R[c])
{
if(!vis[c])
{
cnt++;vis[c]=1;
for(int i=D[c];i!=c;i=D[i])
for(int j=R[i];j!=i;j=R[j])
vis[col[j]]=1;
}
}
return cnt;
}
void Dance(int d)
{
if(d+f()>=ansd)return;
if(R[0]==0)
{
if(ansd>d)ansd=d;
return;
}
int c=R[0];
for(int i=R[0];i;i=R[i])
if(S[i]<S[c])c=i;
for(int i=D[c];i!=c;i=D[i])
{
remove(i);
for(int j=R[i];j!=i;j=R[j])remove(j);
Dance(d+1);
for(int j=L[i];j!=i;j=L[j])restore(j);
restore(i);
}
}
}dlx;
int main()
{
while(scanf("%d%d",&N,&M)!=EOF)
{
int sz=0;
memset(id,0,sizeof(id));
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
{
int x;
scanf("%d",&x);
if(x)id[i][j]=++sz;
}
dlx.init(N*M,sz);
sz=1;
scanf("%d%d",&n,&m);
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
{
for(int x=0;i+x<=N&&x<n;x++)
for(int y=0;j+y<=M&&y<m;y++)
if(id[i+x][j+y])
dlx.Link(sz,id[i+x][j+y]);
sz++;
}
dlx.Dance(0);
printf("%d\n",dlx.ansd);
}
return 0;
}