现在的位置: 首页 > 综合 > 正文

soj 3185: Black and white 最小割

2013年02月01日 ⁄ 综合 ⁄ 共 3793字 ⁄ 字号 评论关闭

Description

Given N black rectangles and M white rectangles.You can pick some of them.But if a black rectangle and a white rectangle share any area, you cannot pick both of them.Can you tell me the maximum of the sum of all you picked rectangles' area?

Input

The first line of the input will be a integer to represent the number of test cases.For each test case there is N+M+1 lines.The first line contains two integers N and M: the number of black rectangles and the number of white rectangles.Followed by N lines
each contains 4 integers x1 y1 x2 and y2.Represent this black rectangle's left-down corner is (x1,y1) and right-up corner is (x2,y2).Followed by M lines each contains 4 integers x1 y1 x2 and y2.Represent this white rectangle's left-down corner is (x1,y1) and
right-up corner is (x2,y2).( 0 <= N,M <= 200 )( 1 <= x1 < x2 <= 10^3 , 1 <= y1 < y2 <= 10^3 )There is a blank line before each test case.

Output

For each test case output the answer on a single line:The maximum of the sum of all you picked rectangles' area.

Sample Input

31 11 1 3 32 2 5 52 01 1 3 32 2 5 51 11 1 3 34 4 5 5

Sample Output

9135

 //

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=55010;
const int M=950000;
const int inf=(1<<28);
int head[N];
struct Edge
{
    int v,next,w;
} edge[M];
int cnt,n,s,t;//n从0开始  0->n-1
void addedge(int u,int v,int w)
{
    edge[cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt++;
    edge[cnt].v=u;
    edge[cnt].w=0;
    edge[cnt].next=head[v];
    head[v]=cnt++;
}
int sap()
{
    int pre[N],cur[N],dis[N],gap[N];
    int flow=0,aug=inf,u;
    bool flag;
    for(int i=0; i<n; i++)
    {
        cur[i]=head[i];
        gap[i]=dis[i]=0;
    }
    gap[s]=n;
    u=pre[s]=s;
    while(dis[s]<n)
    {
        flag=0;
        for(int &j=cur[u]; j!=-1; j=edge[j].next)
        {
            int v=edge[j].v;
            if(edge[j].w>0&&dis[u]==dis[v]+1)
            {
                flag=1;
                if(edge[j].w<aug) aug=edge[j].w;
                pre[v]=u;
                u=v;
                if(u==t)
                {
                    flow+=aug;
                    while(u!=s)
                    {
                        u=pre[u];
                        edge[cur[u]].w-=aug;
                        edge[cur[u]^1].w+=aug;
                    }
                    aug=inf;
                }
                break;
            }
        }
        if(flag) continue;
        int mindis=n;
        for(int j=head[u]; j!=-1; j=edge[j].next)
        {
            int v=edge[j].v;
            if(edge[j].w>0&&dis[v]<mindis)
            {
                mindis=dis[v];
                cur[u]=j;
            }
        }
        if((--gap[dis[u]])==0)
            break;
        gap[dis[u]=mindis+1]++;
        u=pre[u];
    }
    return flow;
}

//初始化  cnt=0;memset(head,-1,sizeof(head));

bool ins(int x1b,int y1b,int x2b,int y2b,int x1w,int y1w,int x2w,int y2w)
{
    if(x1b>=x2w||y1b>=y2w||x2b<=x1w||y2b<=y1w)
        return false;
    return true;
}
int x1b[201],y1b[201],x2b[201],y2b[201];
int x1w[201],y1w[201],x2w[201],y2w[201];
//此题转成求最少拿走多少面积的矩形才能使得剩下的矩形中不存在
//黑与白相交的情况 即最小割问题
//total-最小割=answer
int main()
{
    int ci;scanf("%d",&ci);
    while(ci--)
    {
        int m,p;scanf("%d%d",&m,&p);
        cnt=0;
        memset(head,-1,sizeof(head));
        n=m+p+2;
        s=0,t=n-1;
        int total=0;
        for(int i=1;i<=m;i++)
        {
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            int tmp = (y2-y1)*(x2-x1);
            total+=tmp;
            addedge(s,i,tmp);
            x1b[i]=x1;y1b[i]=y1;x2b[i]=x2;y2b[i]=y2;
        }
        for(int i=1;i<=p;i++)
        {
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            int tmp = (y2-y1)*(x2-x1);
            total+=tmp;
            addedge(m+i,t,tmp);
            x1w[i]=x1;y1w[i]=y1;x2w[i]=x2;y2w[i]=y2;
        }
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=p;j++)
            {
                if(ins(x1b[i],y1b[i],x2b[i],y2b[i],x1w[j],y1w[j],x2w[j],y2w[j]))
                {
                     addedge(i,m+j,inf);
                }
            }
        }
        int mc=sap();
        printf("%d\n",total-mc);
    }
    return 0;
}

 

抱歉!评论已关闭.