题目大意:给定N个矩形,以及N个数字,已知原来每个矩形上面都有一个数字,输出能够确定的矩形和数字的二元组。
这显然是一个一一对应的问题,我们可以把矩形看成左侧的点,把数字看成右侧的点,然后如果点在矩形内,就连一条边,问题变成了求这个二分图的最大匹配,以及判断每条边在最大匹配中是不是必须要选的。
判断每条边在最大匹配中是不是必须要选的办法,就是我们把这条边删去,然后从这个点开始找增广路,如果能找到,就说明这条边不是必须的,否则是必须的。
贴个代码……
#include<iostream>
#include<math.h>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
struct Point
{
int x,y;
};
struct Rect
{
int xmin, xmax, ymin, ymax;
bool in_rect(const Point &p)
{
if(xmin < p.x && p.x < xmax && ymin < p.y && p.y < ymax)
{
return true;
}
return false;
}
};
Rect rect[500];
Point point[500];
int n;
int v1, v2;
int map[500][500];
int match[500];
int ori_match[500];
bool used[500];
pair<int, int> ans[500];
int p_ans=0;
void init()
{
memset(map, 0, sizeof(map));
p_ans=0;
return;
}
bool DFS(int v)
{
used[v] = true;
for(int i=v1+1; i<=v1+v2; i++)
{
if(map[v][i]==1)
{
int w = match[i];
if(w==-1 || (used[w]==0 && DFS(w)==true) )
{
match[v] = i;
match[i] = v;
return true;
}
}
}
return false;
}
int bit_match()
{
int res= 0;
memset(match, -1, sizeof(match));
for(int v=1; v<=v1; v++)
{
if(match[v]==-1)
{
memset(used, 0, sizeof(used));
if(DFS(v))
res++;
}
}
return res;
}
int main()
{
int files=0;
while(true)
{
scanf("%d", &n);
if(n==0)
break;
init();
files++;
int i;
for(i=1; i<=n;i++)
{
scanf("%d %d %d %d", &rect[i].xmin, &rect[i].xmax, &rect[i].ymin, &rect[i].ymax);
}
for(i=1; i<=n; i++)
{
scanf("%d %d", &point[i].x, &point[i].y);
}
int j;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
if(rect[i].in_rect(point[j]))
{
map[i][j+n] = 1;
map[j+n][i] = 1;
}
}
}
v1=n;
v2=n;
bit_match();
memcpy(ori_match, match, sizeof(match));
for(i=1; i<=n;i++)
{
map[i][ ori_match[i] ] = 0;
memset(used, 0, sizeof(used));
match[i]=-1;
match[ori_match[i]]=-1;
if(DFS(i) == false)
{
p_ans++;
ans[p_ans].first = i;
ans[p_ans].second = ori_match[i];
}
map[i][ ori_match[i] ] = 1;
memcpy(match, ori_match, sizeof(ori_match));
}
printf("Heap %d\n", files);
if(p_ans ==0)
{
printf("none");
}
else
{
sort(ans+1, ans+p_ans+1);
for(i=1; i<=p_ans; i++)
{
printf("(%c,%d)", 'A'+ans[i].first-1, ans[i].second-n);
if(i<p_ans)
printf(" ");
}
}
printf("\n");
printf("\n");
}
return 0;
}