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;
}