• 题解 UVA663 Sorting Slides(烦人的幻灯片)


    UVA663 Sorting Slides(烦人的幻灯片)

    第一次做到这么玄学的题,在《信息学奥赛一本通》拓扑排序一章找到这个习题(却发现标程都是错的),结果用二分图匹配做了出来

    蒟蒻感觉思路不太好想,难度大概在蓝题~紫题。。

    那是因为UVa输出换行空格万年老坑

    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define N 27
    int vis[N],match[N],ans[N],x1[N],x2[N],y1[N],y2[N],n,T;
    bool g[N][N],flag;
     
    inline bool dfs(int x) {
        for (register int i=1; i<=n; i++)
            if (!vis[i] && g[x][i]) {
                vis[i]=1;
                if (!ans[i] || dfs(ans[i])) {
                    ans[i]=x;//第 i 个幻灯片对应数字为 x
                    return true;
                }
            }
        return false;
    }
     
    inline int find() {//求二分图最大匹配
        int sum=0;
        memset(ans,0,sizeof ans);
        for (register int x=1; x<=n; x++){
                memset(vis,0,sizeof vis);
                if (dfs(x)) sum++;// 总匹配数
        }
        return sum;
    }
     
    int main() {
        while(~scanf("%d",&n) && n) {
            if (T) puts("");
            printf("Heap %d
    ",++T);
            memset(g,0,sizeof g);
     
            for (int i=1; i<=n; i++)
                scanf("%d%d%d%d",&x1[i],&x2[i],&y1[i],&y2[i]);
                
            for (int i=1,x,y; i<=n; i++) {
                scanf("%d%d",&x,&y);
                for (int j=1; j<=n; j++)
                    if (x>=x1[j] && x<=x2[j] && y>=y1[j] && y<=y2[j])
                        g[i][j]=1;//如果数字在幻灯片范围之内的话则连边,有机会匹配
            }
     
            int tot=find(),flag=0;
    
    

    自此已求出当前的匹配,但程序还未结束,如果在此输出答案:

    	for (int i=1;i<=n;i++) printf("(%c,%d)",i-1+'A',ans[i]);
    

    按照样例数据,你会发现第一组数据已有正确答案,而第二组数据不是none,而输出了匹配情况

    这是因为题目还有一个要求:
    若出现多种对应的情况,我们称这种对应是无法实现的。

    第二组数据中A和B都可以匹配1和2中任意一个,所以对应不唯一

            //接下来我们要去除这种情况
             
            for (int j=1; j<=n; j++)
                for (int i=1;i<=n; i++)
                    if (g[i][j]) {
                        g[i][j]=0;//考虑依次删去每条边,如果有唯一对应,那么至少有一边删去后使匹配数减少
                        if (find()!=tot) {
                            if (flag) printf(" ");
                            else flag=1;
                            printf("(%c,%d)",j-1+'A',i);//如果幻灯片 j 与 数字 i 是唯一搭配,直接输出
                        }
                        g[i][j]=1;
                    }
            if (!flag) printf("none");//如果删去任意一边匹配数都不变,则对应不唯一
            puts("");//相当于printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    Session、Cookie、Application、ViewState和Cache 这四者的区别
    用C#构造HighChart类库,把数据转换成JSON第二阶段完成50%API,已经能满足项目要求了
    HttpHandler 在SharePoint 2010中的应用
    SharePoint 2010 在多台前端环境 还原 网站集 问题解析
    SharePoint 2010 PowerShell 系列 之 文档管理 高级应用和企业案例(文档迁移)
    设计模式策略模式
    CentOS7 安装Hbase集群
    CentOS7 安装zookeeper
    CentOS7 安装Hadoop集群环境
    Django Rest Framework关闭CSRF验证
  • 原文地址:https://www.cnblogs.com/Randolph68706/p/11226249.html
Copyright © 2020-2023  润新知