zoukankan      html  css  js  c++  java
  • 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 ",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 ",++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) ",(char)(last-1+'A'),ans[last]);

            else printf("none ");

            printf(" ");

        }

        return 0;

    }

  • 相关阅读:
    58到家数据库30条军规解读
    mysql那些事(6) WHERE条件 字符串的引号
    按照ID倒序查出某个字段不重复的集合
    mysql那些事(5)建表存储引擎的选择
    mysql那些事(4)建库建表编码的选择
    mysql那些事(3)小数如何存储
    mysql那些事(2)时间类型数据如何存储
    Failed to install apk on device timeout
    daemon not running. starting it now on port 5037 ADB server didn't ACK
    webview
  • 原文地址:https://www.cnblogs.com/philippica/p/4152923.html
Copyright © 2011-2022 走看看