zoukankan      html  css  js  c++  java
  • CF1198E Rectangle Painting 2

    题目

    There is a square grid of size (n×n). Some cells are colored in black, all others are colored in white. In one operation you can select some rectangle and color all its cells in white. It costs (min(h,w)) to color a rectangle of size (h×w). You are to make all cells white for minimum total cost.

    The square is large, so we give it to you in a compressed way. The set of black cells is the union of (m) rectangles.

    大意是给你一个矩形,其中有一些点是黑色的,要你把它染成白色,每次可以选择一个矩形染色,染色的代价是矩形长和宽中较小的那个,问最小代价。

    思路

    网络流。。。

    主要是要把思路打开。

    对于一个染色矩形来说,如果一边的代价确定了,另一边尽量往大了取就是了。
    所以实际上是一次染几行,或几列。

    那么就要求,每一个黑色块至少被以行的形式覆盖或者以列的形式覆盖。

    这就构成了一个网络流的模型。

    我们将源点与每行连接,边权为行的代价,将每列和汇点连接,边权为列的代价,如果某一行和某一列的交界处为黑色,那么就将这一行和这一列连一条边权为oo的边,然后跑一次最小割就是最终答案了。

    代码

    #include<bits/stdc++.h>
    #define M 405
    using namespace std;
    const int inf=1e9;
    int n,m,s,t,h[M],tt=1;
    struct node{int x1,y1,x2,y2;}A[M];
    bool eg[M][M];
    int B1[M*M],b1,B2[M*M],b2;
    struct edge{int nxt,to,co;}G[M*M];
    void Add(int a,int b,int c){
        if(eg[a][b])return;
        G[++tt]=(edge){h[a],b,c};
        h[a]=tt;
        eg[a][b]=1;
    }
    int dep[M],cur[M];
    queue<int>Q;
    bool bfs(){
        memset(dep,-1,sizeof(dep));
        for(int i=s;i<=t;i++)cur[i]=h[i];
        while(!Q.empty())Q.pop();
        Q.push(s);dep[s]=0;
        while(!Q.empty()){
            int x=Q.front();Q.pop();
            for(int i=h[x];i;i=G[i].nxt){
                int u=G[i].to,c=G[i].co;
                if(dep[u]!=-1||!c)continue;
                dep[u]=dep[x]+1;
                if(u==t)return 1;
                Q.push(u);
            }
        }
        return 0;
    }
    int dfs(int x,int mi){
        if(x==t||!mi)return mi;
        int rlow=0,used=0;
        for(int& i=cur[x];i;i=G[i].nxt){
            int u=G[i].to,c=G[i].co;
            if(dep[u]!=dep[x]+1||!c)continue;
            if(rlow=dfs(u,min(c,mi-used))){
                used+=rlow;
                G[i].co-=rlow;
                G[i^1].co+=rlow;
                if(used==mi)break;
            }
        }
        return used;
    }
    int ans=0;
    void Dinic(){
        while(bfs())ans+=dfs(s,inf);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d%d",&A[i].x1,&A[i].y1,&A[i].x2,&A[i].y2);
            B1[++b1]=A[i].x1;B1[++b1]=++A[i].x2;
            B2[++b2]=A[i].y1;B2[++b2]=++A[i].y2;
        }
        B1[++b1]=B2[++b2]=n+1;
        sort(B1+1,B1+b1+1);sort(B2+1,B2+b2+1);
        b1=unique(B1+1,B1+b1+1)-B1-1;
        b2=unique(B2+1,B2+b2+1)-B2-1;
        s=0,t=b1+b2+1;
        for(int i=1;i<=m;i++){
            A[i].x1=lower_bound(B1+1,B1+b1+1,A[i].x1)-B1;
            A[i].x2=lower_bound(B1+1,B1+b1+1,A[i].x2)-B1;
            A[i].y1=lower_bound(B2+1,B2+b2+1,A[i].y1)-B2;
            A[i].y2=lower_bound(B2+1,B2+b2+1,A[i].y2)-B2;
            for(int x=A[i].x1;x<A[i].x2;x++)
                for(int y=A[i].y1;y<A[i].y2;y++)
                    Add(x,y+b1,inf),Add(y+b1,x,0);
        }
        for(int i=1;i<b1;i++){Add(s,i,B1[i+1]-B1[i]);Add(i,s,0);}
        for(int i=1;i<b2;i++){Add(i+b1,t,B2[i+1]-B2[i]);Add(t,i+b1,0);}
        Dinic();printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    AJPFX总结hashmap和hashtable的区别
    AJPFX分享JAVA修饰符详解
    AJPFX分享java排序之希尔排序
    Mysql框架---HMySql
    html/css实现聊天布局
    Java连接Mysql
    微信小程序九宫格布局
    Android设计模式——MVP
    iOS与H5交互(WKWbebView)
    iOS MJExtension的使用
  • 原文地址:https://www.cnblogs.com/zryabc/p/11331988.html
Copyright © 2011-2022 走看看