zoukankan      html  css  js  c++  java
  • CF1198E Rectangle Painting 2(最小割 思维

    这个题主要是转化为最小割的思路不好想到。

    大意:给你一个大的正方形,有的点黑,有的点白,要把黑染白,你每次可以选一个矩形染色,代价是min(长,宽),问最小代价。

    思路:对于一个要染色的块来说,他要被行覆盖或列覆盖(选小的),就是min(占行数,占列数)。然后可以这样建网络流:源点->行结点(容量是占行数)->无穷大的边->列结点(容量是占列数)->汇点,然后跑最小割(最大流)。

    #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;
    }
    
  • 相关阅读:
    POJ 2584 T-Shirt Gumbo (二分图多重最大匹配)
    POJ 2584 T-Shirt Gumbo (二分图多重最大匹配)
    POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)
    POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)
    HDU 4638 Group ★(树状数组)
    HDU 4638 Group ★(树状数组)
    HDU 4632 Palindrome subsequence (区间DP)
    HDU 4632 Palindrome subsequence (区间DP)
    hdu2604 Queuing
    poj3757 Training little cats
  • 原文地址:https://www.cnblogs.com/wzgg/p/11441106.html
Copyright © 2011-2022 走看看