AmazingCounters.com

POJ 1486 Sorting Slides【二分图匹配】

题目大意:有n张幻灯片和n个数字,幻灯片放置有重叠,每个数字隶属于一个幻灯片,现在问你能够确定多少数字一定属于某个幻灯片

思路:上次刷过二分图的必须点后这题思路就显然了 做一次二分匹配后将当前匹配的边删除,再做一次二分匹配,如果能匹配到那么说明这条边不是必须边

顺便说下 删边以后不用从头开始二分匹配,而是在原来二分匹配的基础上对这个点进行增广就行,另外这题格式需要注意,很容易PE

 

#include<cstdio>

#include<string.h>

#include<iostream>

#include<algorithm>

#include<math.h>

#define maxn 10000

#define MOD 1000000007

using namespace std;

int head[maxn],next[maxn],point[maxn],now;

int match[maxn],x1[maxn],x2[maxn],y11[maxn];

int y2[maxn],an[maxn],cop[maxn],ann[maxn];

int rematch[maxn],ans[maxn];

bool visit[maxn];

void add(int x,int y)

{

    next[++now]=head[x];

    head[x]=now;

    point[now]=y;

}

int dfs(int k,int forbid)

{

    for(int i=head[k];i;i=next[i])if(!visit[point[i]])

    if(i!=forbid)

    {

        int u=point[i];

        visit[u]=1;

        if(match[u]==-1||dfs(match[u],forbid))

        {

            match[u]=k;

            an[k]=i;

            return 1;

        }

    }

    return 0;

}

int main()

{

    int n,x,y,cas=0;

    while(1)

    {

        now=0;

        memset(head,0,sizeof(head));

        memset(ans,0,sizeof(ans));

        scanf("%d",&n);

        if(n==0)break;

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

            scanf("%d%d%d%d",&x1[i],&x2[i],&y11[i],&y2[i]);

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

        {

            scanf("%d%d",&x,&y);

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

            if(x1[j]<=x&&x<=x2[j]&&y11[j]<=y&&y<=y2[j])

            {

                add(i,j);

                //printf("%d %d\n",i,j);

            }

        }

        memset(match,-1,sizeof(match));

        memset(an,-1,sizeof(an));

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

        {

            memset(visit,0,sizeof(visit));

            dfs(i,-1);

        }

        //for(int i=1;i<=n;i++)printf("%d  ",match[i]);

        for(int i=1;i<=n;i++)rematch[match[i]]=i;

        memcpy(cop,match,sizeof(match));

        memcpy(ann,an,sizeof(an));

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

        {

            memset(visit,0,sizeof(visit));

            match[rematch[i]]=-1;

            if(!dfs(i,an[i]))ans[rematch[i]]=i;else ans[rematch[i]]=-1;

            memcpy(an,ann,sizeof(an));

            memcpy(match,cop,sizeof(match));

        }

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

        int flag=0,last=-1;

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

        {

            if(ans[i]!=-1)last=i;

        }

        for(int i=1;i<=n;i++)if(ans[i]!=-1 && i!=last)

        {

            flag=1;

            printf("(%c,%d) ",(char)(i-1+'A'),ans[i]);

        }

        if(last!=-1)printf("(%c,%d)\n",(char)(last-1+'A'),ans[last]);

        else printf("none\n");

        printf("\n");

    }

    return 0;

}

posted @ 2014-12-09 12:07  philippica  阅读(214)  评论(0编辑  收藏  举报