POJ 1486 (2分匹配 必须变判断)

建图很好想到,主要是后面判断这条匹配边是不是必须变。 只需要吧当前这个匹配拆开,并且在图中吧这条边去掉。对对于左边的点去找增光路,如果不能找到,说明就是匹配必须边。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#include<stdlib.h>
#include<iostream>
using namespace std;

bool G[30][30];
struct Point
{
    int x,y;
    void read()
    {
        scanf("%d %d",&x,&y);
    }
};
Point rect[30][2];
Point num[30];
bool vis[30];
int link[30];
bool match(int x,int n)
{
    for(int i=1;i<=n;i++)
    {
        if(G[x][i] && !vis[i])
        {
            vis[i]=1;
            if(link[i]==-1 || match(link[i],n))
            {
                link[i]=x;
                return 1;
            }
        }
    }
    return 0;
}

int Hungury(int n)
{
    int ans=0;
    memset(link,-1,sizeof link);
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof vis);
        if(match(i,n))
            ans++;
    }
    return ans;
}
int main()
{
    int n,ca=0;
    while(cin>>n&&n )
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d",&rect[i][0].x,&rect[i][1].x);
            scanf("%d %d",&rect[i][0].y,&rect[i][1].y);
        }
        for(int i=1;i<=n;i++)
            num[i].read();
        memset(G,0,sizeof G);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(rect[i][0].x<num[j].x && num[j].x<rect[i][1].x
                   &&rect[i][0].y<num[j].y && num[j].y<rect[i][1].y)
                    G[j][i]=1;
            }
        }
        printf("Heap %d\n",++ca);
        bool fg=0;
        if(Hungury(n)==n)
            fg=1;
        bool ff=0;
        if(fg)
        {
            for(int i=1;i<=n;i++)
            {
                memset(vis,0,sizeof vis);
                int tmp=link[i];
                G[link[i]][i]=0;
                link[i]=-1;
                if(match(tmp,n))
                {
                    G[tmp][i]=1;
                    continue;
                }
                if(ff)
                    printf(" ");
                ff=1;
                printf("(%c,%d)",i+'A'-1,tmp);
                link[i]=tmp;
                G[tmp][i]=1;
            }
        }
        if(!ff)
            printf("none");
        puts("\n");
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-06 22:20:25

POJ 1486 (2分匹配 必须变判断)的相关文章

POJ 1486 Sorting Slides

http://poj.org/problem?id=1486 题意:给n个矩形的4个边界的坐标(左上和右下),分别是:xmin.xmax.ymin.ymax.又给出四个数字的坐标.每个数字只能属于一个矩形.求出每个数字的从属关系. 题解:二分图最大匹配问题:数字和矩形的匹配.要求出每一条必须边.先求出最大匹配ans,然后删除每一条边,再进行匹配,看最大匹配是否等于ans:如果相等,则这条边不是必须边:如果  小于ans,则这条边是必须边. 注意点:删除边之后要恢复这条边:输出格式-- 1 #in

hdu2444 二分图的匹配,先判断是否为二分图

http://acm.hdu.edu.cn/showproblem.php?pid=2444 Problem Description There are a group of students. Some of them may know each other, while others don't. For example, A and B know each other, B and C know each other. But this may not imply that A and C

POJ 1745 线性和差取余判断

POJ 1745 线性和差取余判断 题目大意:每个数都必须取到,相加或相减去,问所有的方案最后的得数中有没有一个方案可以整除k 这个题目的难点在于dp数组的安排上面 其实也就是手动模仿了一下 比如 一个数,不用说,第一个数之前不用加符号就是本身,那么本身直接对K取余, 那么取17的时候有个余数为2----基础然后来了一个5,(2 + 5)对7取余为0----层层延伸 (2 - 5)对7取余为4(将取余的负数变正) 那么前2个数有余数0和4再来一个-21(0+21)对7取余为0(0-21)对7取余

POJ 1068--Parencodings--括号逆匹配(模拟)

Parencodings Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19655   Accepted: 11870 Description Let S = s1 s2...s2n be a well-formed string of parentheses. S can be encoded in two different ways: q By an integer sequence P = p1 p2...pn

poj 1469 COURSES (二分匹配)

COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16877   Accepted: 6627 Description Consider a group of N students and P courses. Each student visits zero, one or more than one courses. Your task is to determine whether it is poss

poj 1659 Frogs&#39; Neighborhood (Havel-Hakimi定理,判断序列是否可图)

链接:poj 1659 中文题不必解释题意... 其实质是给定一个度序列,判断是否可图, 若可图,输出YES,并输出各顶点之间的连边的情况 否则,输出NO 思路:判断一个序列是否可图,直接利用Havel-Hakimi定理即可 判断任意一个序列是否可图的具体过程: (1)先将序列由大到小排序 (2)设最大的度数为 t ,将最大项删除,然后把最大度数后 (不包括自己)的 t 个度数分别减1(意思就是把度数最大的点与后几个点连边) (3)重复上述两步,如果最大度数t超过了剩下顶点的个数, 或者序列中出

POJ 3057 Evacuation 二分图匹配

每个门每个时间只能出一个人,那就把每个门拆成多个,对应每个时间. 不断增加时间,然后增广,直到最大匹配. //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<

poj 3690 字符矩阵匹配----HASH算法

http://poj.org/problem?id=3690 UVA还有一道也是这样的题,LRJ给的算法是AC自动机----我还没写过,今天用HASH搞了这道题 思路很清晰,但是处理起来还因为HASH函数写混WA了几次... 文本矩阵n*m    T个匹配矩阵p*q 思路: 1.把每一行处理出长为q的hash值 2.对于1中得到的p个哈希值在算一次哈希,这样就把一个矩阵用一个hash值替代了 3.把所有的匹配矩阵压入multiset,然后对于文本矩阵的每一个p*q的子矩阵,算出矩阵哈希值,从mu

学2分匹配 (模版)

转自 http://blog.csdn.net/q3498233/article/details/5786225 二分图:二分图是这样一个图,它的顶点可以分类两个集合X和Y,所有的边关联的两个顶点恰好一个属于集合X,另一个属于集合Y. 二分图匹配:给定一个二分图G,在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点(即2条匹配的边是没有公共顶点),则称M是一个匹配.最大匹配:图中包含边数最多的匹配称为图的最大匹配.完美匹配:如果所有点都在匹配边上,则称这个最大匹配是完美匹配. 二分图