BZOJ2353: Rectangular compression

If a rectangle containing another rectangle $ A $ $ B $, $ A $ then selected from the rectangular obviously not preferable.

The discrete coordinates, a rectangle for each unsigned long long random weights, and the weight of each bin corresponding to the range within or on it are exclusive. Floodfill find the same four communication lattice ownership value, if the shape of a rectangular block is communicated, then the rectangle is a viable total $ O (n ^ 2) $ a.

To make the smallest area and, according to these rectangular area from small to large, washed with n-$ $ rectangular Hungarian algorithm to match the input, the bit operation can be used to accelerate the matching process.

Time complexity $ O (\ frac {n ^ 4} {32}) $.

 

#include<cstdio>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
typedef unsigned int U;
const int N=70,inf=100000;
int n,m,i,j,ca,cb,a[N],b[N];ull w[N],col[N][N],goal;
int xl,xr,yl,yr,area,f[N],cnt,ans;
bool vis[N][N];
U g [N * N], v;
struct Rect{
  int x1,y1,x2,y2,area;
  Rect(){}
  Rect(int _x1,int _y1,int _x2,int _y2,int _area){
    x1=_x1;
    y1=_y1;
    x2=_x2;
    y2 = _y2;
    area=_area;
  }
}rect[N],left[N*N];
inline bool cmp(const Rect&a,const Rect&b){return a.area<b.area;}
void init(int*a,int&n){
  int m=0,i;
  sort(a+1,a+n+1);
  for(i=1;i<=n;i++)if(i==1||a[i]>a[m])a[++m]=a[i];
  n=m;
}
void cov(int A,int B,int C,int D,ull E){
  int i,j;
  for(i=1;i<=ca;i++)if(a[i]>=A&&a[i+1]<=B)for(j=1;j<=cb;j++)if(b[j]>=C&&b[j+1]<=D)col[i][j]^=E;
}
void dfs(int x,int y){
  if(x<1||x>ca||y<1||y>cb)return;
  if(col[x][y]!=goal)return;
  if(vis[x][y])return;
  am [x] [y] = 1;
  area+=(a[x+1]-a[x])*(b[y+1]-b[y]);
  xl=min(xl,a[x]);
  xr=max(xr,a[x+1]);
  yl = min (yl, b [y]);
  yr=max(yr,b[y+1]);
  dfs(x-1,y);
  dfs(x+1,y);
  dfs(x,y-1);
  dfs(x,y+1);
}
inline bool inside(const Rect&A,const Rect&B){
  return A.x1>=B.x1&&A.x2<=B.x2&&A.y1>=B.y1&&A.y2<=B.y2;
}
bool find(int x){
  while(1){
    U t=v&g[x];
    if(!t)return 0;
    int y=__builtin_ctz(t);
    v^=1U<<y;
    if(!f[y]||find(f[y]))return f[y]=x,1;
  }
  return 0;
}
int main () {
  scanf("%d",&n);
  for(i=1;i<=n;i++)scanf("%d",&rect[i].x1);
  for(i=1;i<=n;i++)scanf("%d",&rect[i].y1);
  for(i=1;i<=n;i++)scanf("%d",&rect[i].x2);
  for(i=1;i<=n;i++)scanf("%d",&rect[i].y2);
  for(i=1;i<=n;i++){
    a[++ca]=rect[i].x1,a[++ca]=rect[i].x2;
    b[++cb]=rect[i].y1,b[++cb]=rect[i].y2;
  }
  init(a,ca);
  init(b,cb);
  as - cb--;
  for(i=1;i<=n;i++)w[i]=w[i-1]*233+10007;
  for(i=1;i<=n;i++)cov(rect[i].x1,rect[i].x2,rect[i].y1,rect[i].y2,w[i]);
  for(i=1;i<=ca;i++)for(j=1;j<=cb;j++)if(!vis[i][j]&&col[i][j]){
    xl=inf,xr=-inf;
    yl=inf,yr=-inf;
    area=0;
    goal=col[i][j];
    dfs(i,j);
    if((xr-xl)*(yr-yl)==area)left[++m]=Rect(xl,yl,xr,yr,area);
  }
  sort(left+1,left+m+1,cmp);
  for(i=1;i<=m;i++)for(j=1;j<=n;j++)if(inside(left[i],rect[j]))g[i]|=1U<<(j-1);
  for(i=1;i<=m;i++){
    v=(1U<<n)-1;
    if(find(i))cnt++,ans+=left[i].area;
  }
  if(cnt<n)ans=-1;
  return printf("%d",ans),0;
}

  

Guess you like

Origin www.cnblogs.com/clrs97/p/12154237.html