题意:给出一些矩形的坐标和一些点的坐标,若点在矩形内,则该点和该矩形匹配,问是否存在确定的匹配。
思路:模拟这个过程。每次找度为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; }