题意:

      有n个矩形,每个矩形上的某个位置上都有一个点,但是由于矩形是透明的,当一些矩形重叠在一起的时候就很可能分不清哪个点是那个矩形的,给你n个矩形的坐标,还有n个点的坐标,然后让你找出所有能确定的点。

思路:

       两种方法做的,第一种是用的模拟的方法,我是这么想的,如果把一个状态给我们自己我们会怎么判断?我肯定是先找到我一眼就能看出来的删除,什么样的算是可以删除的?如果一个框上只有一个点,或者一个点只在一个框上,那么就可以肯定找到了一对,这样做的话要考虑到一个问题,那么就是有对是一看看不出来的,也就是说一开始断定不了,随着一些可以断定的删除之后就可以断定了,所以要while(1)循环的去找,这样显然是能搞定的,写的时候可以存两个方向的图,还有度数...模拟细节不啰嗦,然后就是第二种方法,这个方法比较容易写,也是大多数人认可的方法,但是一开始我并没有写,原因是我很难说服我自己这种方法是对的,因为我总担心,如果当前这条边不是匹配的关键边,但是随着别的边的删除,后来不是匹配的有成了匹配的怎么办?这么想可能是因为我写的第一种方法while(1)的原因,后来就是不停的自己画画画,终于明白了,哎!其实是我自己想多了,首先用匹配去做与我的第一种方法根本没有任何关联,也就是思路完全不同,匹配的思路就是只要是关键边,那么删除之后肯定是对匹配数有影响,如果没有影响的边,无论怎么while(1)最后还是没有影响,因为至少出现一组可以和他替换的边,这么这两组(或多组)可以互相替换的边彼此束缚着对方,就像是死锁一样,已经死锁的关联进程中,无论你以什么样的顺序去尝试执行都没意义,因为你“在环里了”,匹配的实现起来比较简单,直接匹配一遍,然后尝试删除匹配好的边就行了。

    

#include<stdio.h>

#include<string.h>

#include<algorithm>

#define N_node 26 + 5

#define N_edge 26 * 26 + 10

using namespace std;

typedef struct

{

    int to ,next;

}STAR;

typedef struct

{

    int x1 ,x2 ,y1 ,y2;

}EDGE;

typedef struct

{

    int x ,y;

}NODE;

typedef struct

{

    int id;

    char c;

}ANS;

ANS ans[N_node];

STAR E[N_edge];

EDGE edge[N_node];

NODE node[N_node];

int list[N_node] ,tot;

int mkdfs[N_node] ,mkgx[N_node];

int p1[N_node] ,p2[N_node];

void add(int a ,int b)

{

    E[++tot].to = b;

    E[tot].next = list[a];

    list[a] = tot;

}

int DFS_XYL(int x ,int a ,int b)

{

    for(int k = list[x] ;k ;k = E[k].next)

    {

        int to = E[k].to;

        if(x == a && b == to)

        continue;

        if(mkdfs[to]) continue;

        mkdfs[to] = 1;

        if(mkgx[to] == -1 || DFS_XYL(mkgx[to] ,a ,b))

        {

            mkgx[to] = x;

            return 1;

        }

    }

    return 0;

}

int XYL(int n ,int a ,int b)

{

    memset(mkgx ,255 ,sizeof(mkgx));

    int ans = 0;

    for(int i = 1 ;i <= n ;i ++)

    {

        memset(mkdfs ,0 ,sizeof(mkdfs));

        ans += DFS_XYL(i ,a ,b);

    }

    return ans;

}

bool jude(EDGE a ,NODE b)

{

    return a.x1 <= b.x && a.x2 >= b.x && a.y1 <= b.y && a.y2 >= b.y;

}

bool camp(ANS a ,ANS b)

{

    return a.c < b.c;

}

int main ()

{

    int n ,i ,j ,cas = 1;

    while(~scanf("%d" ,&n) && n)

    {

        for(i = 1 ;i <= n ;i ++)

        scanf("%d %d %d %d" ,&edge[i].x1 ,&edge[i].x2 ,&edge[i].y1 ,&edge[i].y2);

        for(i = 1 ;i <= n ;i ++)

        scanf("%d %d" ,&node[i].x ,&node[i].y);

        memset(list ,0 ,sizeof(list));

        tot = 1;

        for(i = 1 ;i <= n ;i ++)

        for(j = 1 ;j <= n ;j ++)

        if(jude(edge[i] ,node[j]))

        add(i ,j);

        XYL(n ,0 ,0);

        for(i = 1 ;i <= n ;i ++)

        p1[i] = mkgx[i] ,p2[i] = i;

        int ansid = 0;

        for(i = 1 ;i <= n ;i ++)

        {

            if(XYL(n ,p1[i] ,p2[i]) != n)

            {

                ans[++ansid].c = p1[i] + 'A' - 1;

                ans[ansid].id = p2[i];

            }

        }

        printf("Heap %d\n" ,cas ++);

        if(!ansid) printf("none\n");

        else

        {

            sort(ans + 1 ,ans + ansid + 1 ,camp);

            for(i = 1 ;i <= ansid ;i ++)

            {

                if(i == 1) printf("(%c,%d)" ,ans[i].c ,ans[i].id);

                else printf(" (%c,%d)" ,ans[i].c ,ans[i].id);

            }

            printf("\n");

        }

        printf("\n");

    }

}

      

      

#include<stdio.h>

#include<string.h>

#include<algorithm>

#define N_node 26 + 5

#define N_edge 26 * 26 + 10

using namespace std;

typedef struct

{

    int to ,next;

}STAR;

typedef struct

{

    int x1 ,y1 ,x2 ,y2;

}HDP;

typedef struct

{

    int x ,y;

}NODE;

typedef struct

{

    char c;

    int id;

}ANS;

STAR E1[N_edge] ,E2[N_edge];

HDP hdp[N_node];

NODE node[N_node];

ANS ans[N_node];

int list1[N_node] ,list2[N_node] ,tot;

int dep1[N_node] ,mkuse1[N_node];

int dep2[N_node] ,mkuse2[N_node];

bool camp(ANS a ,ANS b)

{

    return a.c < b.c;

}

void add(int a ,int b)

{

    E1[++tot].to = b;

    E1[tot].next = list1[a];

    list1[a] = tot;

    E2[tot].to = a;

    E2[tot].next = list2[b];

    list2[b] = tot;

}

bool jude(HDP a ,NODE b)

{

    return a.x1 <= b.x && a.x2 >= b.x && a.y1 <= b.y && a.y2 >= b.y;

}

int main ()

{

    int n ,i ,j ,cas = 1;

    while(~scanf("%d" ,&n) && n)

    {

        for(i = 1 ;i <= n ;i ++)

        scanf("%d %d %d %d" ,&hdp[i].x1 ,&hdp[i].x2 ,&hdp[i].y1 ,&hdp[i].y2);

        for(i = 1 ;i <= n ;i ++)

        scanf("%d %d" ,&node[i].x ,&node[i].y);

        memset(list1 ,0 ,sizeof(list1));

        memset(list2 ,0 ,sizeof(list2));

        tot = 1;

        memset(dep1 ,0 ,sizeof(dep1));

        memset(dep2 ,0 ,sizeof(dep2));

        for(i = 1 ;i <= n ;i ++)

        for(j = 1 ;j <= n ;j ++)

        if(jude(hdp[i] ,node[j]))

        {

            add(i ,j);

            dep1[i] ++;

            dep2[j] ++;

        }

        int ansid = 0;

        memset(mkuse1 ,0 ,sizeof(mkuse1));

        memset(mkuse2 ,0 ,sizeof(mkuse2));

        while(1)

        {

            int mk = 0;

            for(i = 1 ;i <= n ;i ++)

            {

                if(dep1[i] == 1 && !mkuse1[i])

                {

                    mkuse1[i] = 1;

                    mk = 1;

                    int to;

                    for(int k = list1[i] ;k ;k = E1[k].next)

                    {

                        if(!mkuse2[E1[k].to])

                        {

                            mkuse2[E1[k].to] = 1;

                            to = E1[k].to;

                            break;

                        }

                    }

                    dep2[to] --;

                    for(int k = list2[to] ;k ;k = E2[k].next)

                    dep1[E2[k].to] --;

                    ans[++ansid].c = i + 'A' - 1;

                    ans[ansid].id = to;

                }

            }

            for(i = 1 ;i <= n ;i ++)

            {

                if(dep2[i] == 1 && !mkuse2[i])

                {

                    mkuse2[i] = 1;

                    mk = 1;

                    int to;

                    for(int k = list2[i] ;k ;k = E2[k].next)

                    {

                        if(!mkuse1[E2[k].to])

                        {

                            mkuse1[E2[k].to] = 1;

                            to = E2[k].to;

                            break;

                        }

                    }

                    dep1[to] --;

                    for(int k = list1[to] ;k ;k = E1[k].next)

                    dep2[E1[k].to] --;

                    ans[++ansid].c = to + 'A' - 1;

                    ans[ansid].id = i;

                }

            }

            if(!mk) break;

        }

        printf("Heap %d\n" ,cas ++);

        if(!ansid) printf("none\n");

        else

        {

            sort(ans + 1 ,ans + ansid + 1 ,camp);

            for(i = 1 ;i <= ansid ;i ++)

            {

                if(i == 1) printf("(%c,%d)" ,ans[i].c ,ans[i].id);

                else printf(" (%c,%d)" ,ans[i].c ,ans[i].id);

            }

            printf("\n");

        }

        printf("\n");

    }

    return 0;

}

POJ1486模拟或者匈牙利变种的更多相关文章

  1. RNN(2) ------ “《A Critical Review of Recurrent Neural Networks for Sequence Learning》RNN综述性论文讲解”(转载)

    原文链接:http://blog.csdn.net/xizero00/article/details/51225065 一.论文所解决的问题 现有的关于RNN这一类网络的综述太少了,并且论文之间的符号 ...

  2. [Lydsy1805月赛]quailty 算法 BZOJ5362

    分析: 题目中描述了一个二分图,让我们求最小权最大匹配,实际上其实是求n个点,在n*(n-1)/2中选n条边的权值和最小,形成一个每个点都有出边的体系,也就是基环树,(证明:因为我们需要二分图最大匹配 ...

  3. NOIP 模拟 box - 费用流 / 匈牙利

    题目大意: 给出n(\(\le 200\))个盒子,第i个盒子长\(x_i\),宽\(y_i\),一个盒子可以放入长宽都大于等于它的盒子里,并且每个盒子里只能放入一个盒子(可以嵌套),嵌套的盒子的占地 ...

  4. BZOJ3291Alice与能源计划——匈牙利算法+模拟费用流

    题目描述 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验.为 了方便,我们可以将火星抽象成平面,并建立平面直角坐标系.火星上一共有N个居民点 ...

  5. BZOJ2557[Poi2011]Programming Contest——匈牙利算法+模拟费用流

    题目描述 Bartie and his friends compete in the Team Programming Contest. There are n contestants on each ...

  6. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

  7. HDU5090--Game with Pearls 二分图匹配 (匈牙利算法)

    题意:给N个容器,每个容器里有一定数目的珍珠,现在Jerry开始在管子上面再放一些珍珠,放上的珍珠数必须是K的倍数,可以不放.最后将容器排序,如果可以做到第i个容器上面有i个珍珠,则Jerry胜出,反 ...

  8. java 工厂的变形模拟的各种应用

    工厂模式是在项目开发中使用效率高,意一个接口,该定义用于创建对象.让子类来决定哪一个类实例. 这就是一个工厂类的示意图 接着来一个简单的样例: 如上图所看到的,我们首先定义我们的产品抽象类接口,也能够 ...

  9. 模拟Paxos算法及其简单学习总结

    一.导读 Paxos算法的流程本身不算很难,但是其推导过程和证明比较难懂.在Paxos Made Simple[1]中虽然也用了尽量简化的流程来解释该算法,但其实还是比较抽象,而且有一些细节问题没有交 ...

随机推荐

  1. C语言中指针和多维数组

    指针和多维数组 数组名是特殊的指针 数组是一个特殊的指针,多维数组也是更为复杂的数组,它们的关系是什么样的呢? 我们通过一个简单的例子来比较形象的了解指针和多维数组: int a[2][3]; 这是一 ...

  2. IDEA中便捷内存数据库H2的最简使用方式

    在IDEA中有时候为了练习,需要使用到数据库,但如果自己工作或开发机子上本来没有安装数据库,也没有可用的远程数据库时,我们可以直接在IDEA环境上使用便捷式的内存数据库H2,关于H2更多知识就自己去找 ...

  3. Typescript开发学习总结(附大量代码)

    如果评定前端在最近五年的重大突破,Typescript肯定能名列其中,重大到各大技术论坛.大厂面试都认为Typescript应当是前端的一项必会技能.作为一名消息闭塞到被同事调侃成"新石器时 ...

  4. 关于djangorestframework

    djangorestframework技术文档 restfrmework规范 开发模式 普通开发为前端和后端代码放在一起写 前后端分离为前后端交互统统为ajax进行交互 前后端分离 优点:分工明细,节 ...

  5. FreeBSD 12.2 vmware 虚拟机镜像 bt 种子

    安装了 KDE5 火狐浏览器 Fcitx 输入法 并进行了中文设置 替换软件源为国内可用. VirtualBox虚拟机也可以用  magnet:?xt=urn:btih:E88885631B57426 ...

  6. 使用quartz.net 完成一个winform版的任务提醒工具

    这个任务提醒工具是这样的,是每日定时执行,触发时间为 小时和分钟.每天早上来就可以把当天要做的添加到datagridview中,只记录了标题和内容和时间.双击dgv就查看内容. 如果每天计划重复,也可 ...

  7. 微信小程序应用开发-手动创建

    基础知识: index.wxml的代码为 Html,有很多标签,如等 index.wwss相当于css 即样式 index.js中有很多函数,可自定义 操作步骤: 删除app.json文件中page/ ...

  8. 攻防世界 reverse Newbie_calculations

    Newbie_calculations Hack-you-2014 题目名百度翻译成新手计算,那我猜应该是个实现计算器的题目.... IDA打开程序,发现一长串的函数反复调用,而且程序没有输入,只有输 ...

  9. 仿VUE创建响应式数据

    VUE对于前端开发人员都非常熟悉了,其工作原理估计也都能说的清个大概,具体代码的实现估计看的人不会太多,这里对vue响应式数据做个简单的实现. 先简单介绍一下VUE数据响应原理,VUE响应数据分为对象 ...

  10. 【秒懂音视频开发】14_AAC编码

    AAC(Advanced Audio Coding,译为:高级音频编码),是由Fraunhofer IIS.杜比实验室.AT&T.Sony.Nokia等公司共同开发的有损音频编码和文件格式. ...