• codeforces 1198E Rectangle Painting 2 最小点覆盖


    题目传送门

    题意:

      有一个$n∗n$的网格,网格中有一些矩形是黑的,其他点都是白的。

      你每次可以花费$ min (h,w)$的代价把一个$h*w$的矩形区域变白。求把所有黑格变白的最小代价。

    思路:

      对于一列来说,如果我们要把这一列涂白,那必定会一涂到底,这样对结果只会有好处。行也是这样。

      明白了这个之后,这道题就变成了一道需要离散化的最小点覆盖问题,离散化时注意这个是网格,所以$x2,y2$都需要加1处理,然后跑一边网络流即可。

    #pragma GCC optimize (2)
    #pragma G++ optimize (2)
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<bits/stdc++.h>
    #include<unordered_map>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define dep(i,b,a) for(int i=b;i>=a;--i)
    #define clr(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    #define pii pair<int,int >
    using namespace std;
    typedef long long ll;
    ll rd()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int inf=0x3f;
    const int maxn=8e5+10;
    const ll INFLL = 0x3f3f3f3f3f3f3f3f;
    const int INF = 0x3f3f3f3f;
    
    struct Edge {
        int to, flow, nxt;
        Edge(){}
        Edge(int to, int nxt, int flow):to(to),nxt(nxt), flow(flow){}
    }edge[maxn << 2];
    
    int head[maxn], dep[maxn];
    int S, T;
    int N, n, m, tot;
    
    void Init(int n)
    {
        N = n;
        for (int i = 0; i <= N; ++i) head[i] = -1;
        tot = 0;
    }
    
    void addv(int u, int v, int w, int rw = 0)
    {
        edge[tot] = Edge(v, head[u], w); head[u] = tot++;
        edge[tot] = Edge(u, head[v], rw); head[v] = tot++;
    }
    
    bool BFS()
    {
        for (int i = 0; i <= N; ++i) dep[i] = -1;
        queue<int>q;
        q.push(S);
        dep[S] = 1;
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            for (int i = head[u]; ~i; i = edge[i].nxt)
            {
                if (edge[i].flow && dep[edge[i].to] == -1)
                {
                    dep[edge[i].to] = dep[u] + 1;
                    q.push(edge[i].to);
                }
            }
        }
        return dep[T] < 0 ? 0 : 1;
    }
    
    int DFS(int u, int f)
    {
        if (u == T || f == 0) return f;
        int w, used = 0;
        for (int i = head[u]; ~i; i = edge[i].nxt)
        {
            if (edge[i].flow && dep[edge[i].to] == dep[u] + 1)
            {
                w = DFS(edge[i].to, min(f - used, edge[i].flow));
                edge[i].flow -= w;
                edge[i ^ 1].flow += w;
                used += w;
                if (used == f) return f;
            }
        }
        if (!used) dep[u] = -1;
        return used;
    }
    
    int Dicnic()
    {
        int ans = 0;
        while (BFS())
        {
            ans += DFS(S, INF);
        }
        return ans;
    }
    vector<int >vx,vy;
    struct node{
        int x1,y1,x2,y2;
    }a[60];
    int main()
    {
        while (~scanf("%d %d", &n, &m))
        {
            rep(i,1,m){
                scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
                a[i].x2++,a[i].y2++;
                vx.pb(a[i].x1),vx.pb(a[i].x2);
                vy.pb(a[i].y1),vy.pb(a[i].y2);
            }
            sort(vx.begin(),vx.end());
            vx.erase(unique(vx.begin(),vx.end()),vx.end());
            sort(vy.begin(),vy.end());
            vy.erase(unique(vy.begin(),vy.end()),vy.end());
            int tx=vx.size(),ty=vy.size();
            S = 0, T = tx * ty+1;
            Init(T);
            for(int i=0;i<tx-1;i++){
                addv(S,i+1,vx[i+1]-vx[i]);
            }
            for(int i=0;i<ty-1;i++){
                addv(tx+i+1,T,vy[i+1]-vy[i]);
            }
            for(int i=0;i<tx-1;i++){
                for(int j=0;j<ty-1;j++){
                    rep(k,1,m){
                        if(a[k].x1<=vx[i]&&a[k].x2>=vx[i+1]&&a[k].y1<=vy[j]&&a[k].y2>=vy[j+1]){
                            addv(i+1,tx+j+1,INF);
                        }
                    }
                }
            }
    //        printf("debug
    ");
            int ans = Dicnic();
            printf("%d
    ", ans);
        }
    }
  • 相关阅读:
    烧写NAND Flash时出现错误:*** Warning bad CRC or NAND, using default environment
    在ubuntu下如何验证文件的MD5码
    条件编译#ifdef MACRO_A和#if defined(MACRO_A)的区别
    用nmap获取ip和mac地址
    rcS中启动udevd
    ubuntu下minicom不能接受键盘输入
    ios audioqueue 流播放接口
    ffmpeg 0.8.11 VC编译的SDK已经发布
    lua 字符串数学表达式运算
    ffmpeg 0.8.11 VC编译的SDK已经发布
  • 原文地址:https://www.cnblogs.com/mountaink/p/11614080.html
Copyright © 2020-2023  润新知