您的位置:首页 > 其它

POJ 1486 - Sorting Slides 二分匹配 必须边

2017-10-06 14:34 351 查看
枚举每一个边,看看最大匹配数是否会减少即可

#include<cstdio>  

#include<cstring>  

using namespace std;  

const int maxn=26+5;  

  

struct Max_Match  

{  

    int n,m;  

    bool g[maxn][maxn];  

    bool vis[maxn];  

    int left[maxn];  

  

    void init(int n)  

    {  

        this->n=n;  

        memset(g,0,sizeof(g));  

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

    }  

  

    bool match(int u)  

    {  

        for(int v=1;v<=n;v++)if(g[u][v] && !vis[v])  

        {  

            vis[v]=true;  

            if(left[v]==-1 || match(left[v]))  

            {  

                left[v]=u;  

                return true;  

            }  

        }  

        return false;  

    }  

  

    int solve()  

    {  

        int ans=0;  

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

        {  

            memset(vis,0,sizeof(vis));  

            if(match(i)) ans++;  

        }  

        return ans;  

    }  

}MM;  

  

int xmin[maxn],ymin[maxn],xmax[maxn],ymax[maxn];  

struct  

{  

    int x;  // edge[i].x=x 表示第i个矩形配对的数字 是x;  

    bool ok;//标记该边是否是 必需边  

}edge[maxn];  

  

int main()  

{  

    int n,kase=0;  

    while(scanf("%d",&n)==1&&n)  

    {  

        MM.init(n);  

        memset(edge,0,sizeof(edge));  

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

        {  

            scanf("%d%d%d%d",&xmin[i],&xmax[i],&ymin[i],&ymax[i]);  

        }  

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

        {  

            int x,y;  

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

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

            {  

                if(xmin[j]<=x&&x<=xmax[j]&&ymin[j]<=y&&y<=ymax[j])  

                    MM.g[j][i]=true;  

            }  

        }  

        MM.solve();  

        int edge_num=n;  

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

        {  

            edge[MM.left[i]].x=i;  

            edge[MM.left[i]].ok=true;  

        }  

        for(int i=1;i<=n;i++)//尝试删除第i条匹配边  

        {  

            int j=edge[i].x;  

            MM.g[i][j]=false;//删除此边  

            memset(MM.left,-1,sizeof(MM.left));  

            int num = MM.solve();  

            if(num == n)//删除边后,匹配数不变  

            {  

                edge[i].ok=false;  

                edge_num--;  

            }  

            MM.g[i][j]=true;//还原此边  

        }  

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

        if(edge_num==0) printf("none\n");  

        else  

        {  

            for(int i=1;i<=n;i++)if(edge[i].ok)  

                printf("(%c,%d) ",i-1+'A',edge[i].x);  

            printf("\n");  

        }  

        printf("\n");  

    }  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: