把大矩形的每个小格子都看成我们想要使其有1的一列 每块碎片都看作一行01串 之前在这里卡了很久 然后没理由的看到了kuangbin博客里的这句“把每个格子当成一个列,要覆盖所有格子。” 突然就懂了
套模板的时候还是要注意一下细节
比如UDLR代表的是每一个元素的上下左右 那么最多有多少元素呢?之前一直觉得是n*m个 其实还是对算法不熟悉 看到罗老师的代码之后就突然想起来了n*m是列 t是行 那么N就是要开到n*m*t 这个数量级的
比如link那里 一定是i*m+j而不是i*n+j 否则会蜜汁tle 我还头铁交了几发 = = 对横纵坐标直觉不够 还半天想不清楚
比如dance的参数k 第一遍写的时候甚至想引入另一个step参数来记录答案= =
比如刚开始想到了应该要剪枝 但是半天怎么剪枝都没想清楚 然后tle一发之后又马上想到了这个本来就不难的剪枝= =
#include <cstdio>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int N=1e5;
const int Q=1e3;
int L[N],R[N],U[N],D[N];//上下左右的指向
int H[N];//行头指针
int C[N],M[N];//元素所在行列
int S[N];//每一列的元素数量
void link(int row,int col,int id)
{
C[id]=col;M[id]=row;
U[id]=U[col];D[id]=col;
D[U[col]]=id;U[col]=id;
if(H[row]==-1)
{
H[row]=L[id]=R[id]=id;
}
else
{
L[id]=L[H[row]];R[L[id]]=id;
L[H[row]]=id;R[id]=H[row];
}
S[col]++;
}
void remove(int col)
{
R[L[col]]=R[col];
L[R[col]]=L[col];
for(int i=D[col];i!=col;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(int col)
{
R[L[col]]=col;
L[R[col]]=col;
for(int i=U[col];i!=col;i=U[i])
{
for(int j=L[i];j!=i;j=L[j])
{
U[D[j]]=j;
D[U[j]]=j;
S[C[j]]++;
}
}
}
int ans;
void init(int t,int m)
{
ans=inf;
for(int i=0;i<=t;i++)//初始化
{
H[i]=-1;
}
for(int i=0;i<=m;i++)//初始化
{
L[i+1]=i;
R[i]=i+1;
U[i]=D[i] = i;
S[i]=0;
}
L[0]=m;
R[m]=0;
}
void dance(int k)
{
if(k>=ans)return;
if(!R[0])
{
ans=min(k,ans);
}
int col=R[0];
for(int i=R[0];i;i=R[i])
if(S[i]<S[col])
col=i;
remove(col);
for(int i=D[col];i!=col;i=D[i])
{
for(int j=R[i];j!=i;j=R[j])
remove(C[j]);
dance(k+1);
// if(dance(k+1))return true;
for(int j=L[i];j!=i;j=L[j])
resume(C[j]);
}
resume(col);
// return false;
}
///把每个格子当成一列 然后每个碎片就是一行
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
int T,n,m,x1,y1,x2,y2,t;
scanf("%d",&T);
// cin>>T;
while(T--)
{
scanf("%d%d%d",&n,&m,&t);
// cin>>n>>m>>t;
init(t,n*m);
int id=n*m+1;
for(int k=1;k<=t;k++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
// cin>>x1>>y1>>x2>>y2;
for(int i=x1;i<x2;i++)
{
for(int j=y1+1;j<=y2;j++)
{
// cout<<"i*m+j="<<i*m+j<<endl;
// link(k,i*n+j,id++);
link(k,i*m+j,id++);
}
}
}
dance(0);
if(ans!=inf)
printf("%d\n",ans);
// cout<<ans<<endl;
else
printf("-1\n");
// cout<<-1<<endl;
}
return 0;
}