裸= =
模板题。只需要建图的时候注意一下。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define maxn 505*909
#define inf 0x3f3f3f3f
using namespace std;
int n,m,p;
int map[505][909];
int L[maxn],R[maxn],D[maxn],U[maxn],S[maxn],col[maxn],row[maxn],head,cnt;
int num;
void dancing_links_init()
{
head=0;
memset(S,0,sizeof S);
for(int i=head;i<=m;i++)
{
R[i]=(i+1)%(m+1);
L[i]=(i-1+m+1)%(m+1);
U[i]=D[i]=i;
}
cnt=m+1;
for(int i=1;i<=n;i++)
{
int rowh=-1;
for(int j=1;j<=m;j++)
{
if(map[i][j])
{
S[j]++;
U[cnt]=U[j];
D[U[j]]=cnt;
U[j]=cnt;
D[cnt]=j;
row[cnt]=i;
col[cnt]=j;
if(rowh==-1)
{
L[cnt]=R[cnt]=cnt;
rowh=cnt;
}
else
{
L[cnt]=L[rowh];
R[L[rowh]]=cnt;
R[cnt]=rowh;
L[rowh]=cnt;
}
cnt++;
}
}
}
}
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[col[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])
{
++S[col[j]];
U[D[j]]=j;
D[U[j]]=j;
}
}
L[R[c]]=c;
R[L[c]]=c;
}
void dfs(const int &k)
{
if(R[head]==head)
{
if(k<num)num=k;
return;
}
if(k>=num)return;
int mx=inf,cur=0;
for(int t=R[head];t!=head;t=R[t])
{
if(S[t]<mx)
{
mx=S[t];
cur=t;
}
}
Remove(cur);
for(int i=D[cur];i!=cur;i=D[i])
{
for(int j=R[i];j!=i;j=R[j])
{
Remove(col[j]);
}
dfs(k+1);
for(int j=L[i];j!=i;j=L[j])
{
Resume(col[j]);
}
}
Resume(cur);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
num=inf;
memset(map,0,sizeof map);
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=p;i++)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
for(int j=x1+1;j<=x2;j++)
for(int k=y1+1;k<=y2;k++)
map[i][(j-1)*m+k]=1;
}
m=n*m;
n=p;
dancing_links_init();
dfs(0);
if(num==inf)printf("-1\n");
else printf("%d\n",num);
}
return 0;
}