题意:给出一些矩形的坐标和一些点的坐标,若点在矩形内,则该点和该矩形匹配,问是否存在确定的匹配。
思路:模拟这个过程。每次找度为1的点,则其对应匹配定是确定的。然后将与其邻点关联的边都删除,继续迭代。可以根据topsort的思路用一个队列来存放度数为1的点。(其他思路:这题可以先任意找出一个完美匹配,然后依次删除该匹配的每一条边,若仍能构成完美匹配,则这个匹配不唯一,若不能构成完美匹配,则该匹配唯一)。下面程序里N值设为30则re,开大才能ac。暂时不清楚为什么。
#include <stdio.h>
#include <string.h>
#define N 1000
struct point{
int l,r,u,d;
}p[N];
struct edge{
int y,next;
}e[N*N*2];
int c=1,n,first[N],top,d[N],q[N<<1],res[N],used[N];
int test(int x,int y,int j){
return (x>p[j].l&&x<p[j].r&&y>p[j].d&&y<p[j].u);
}
void add(int x,int y){
e[top].y = y;
e[top].next = first[x];
first[x] = top++;
}
int main(){
while(scanf("%d",&n) && n){
int i,j,front,rear,now,x,y;
front = rear = -1;
top = 0;
memset(used, 0, sizeof(used));
memset(res,0,sizeof(res));
memset(d, 0, sizeof(d));
memset(first, -1, sizeof(first));
for(i = 1;i<=n;i++)
scanf("%d %d %d %d",&p[i].l,&p[i].r,&p[i].d,&p[i].u);
for(i = 1;i<=n;i++){
scanf("%d %d",&x,&y);
for(j = 1;j<=n;j++)
if(test(x,y,j)){
add(j,i+n);
add(i+n,j);
d[j]++;
d[i+n]++;
}
}
for(i = 1;i<=n<<1;i++)
if(d[i] == 1)
q[++rear] = i;
while(front < rear){
now = q[++front];
if(used[now])
continue;
d[now] = -1;
used[now] = 1;
for(i = first[now];i!=-1;i=e[i].next){
y = e[i].y;
if(!used[y]){
used[y] = 1;
d[y] = -1;
if(now < y)
res[now] = y;
else
res[y] = now;
for(j = first[y];j!=-1;j=e[j].next){
d[e[j].y]--;
if(d[e[j].y] == 1 && !used[e[j].y])
q[++rear] = e[j].y;
}
}
}
}
printf("Heap %d\n",c++);
for(i = 1;i<=26;i++)
if(res[i])
printf("(%c,%d) ",i+'A'-1,res[i]-n);
if(rear == -1)
printf("none");
printf("\n\n");
}
return 0;
}