poj 1486 模拟(透明胶片确定对应数字)

题意:给出一些矩形的坐标和一些点的坐标,若点在矩形内,则该点和该矩形匹配,问是否存在确定的匹配。

思路:模拟这个过程。每次找度为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;
}


你可能感兴趣的:(poj 1486 模拟(透明胶片确定对应数字))