zoukankan      html  css  js  c++  java
  • 题解 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;
    }
    
  • 相关阅读:
    古谚、评论与论断、名篇与名言
    重读《西游记》
    重读《西游记》
    命名之法 —— 时间、季节、地点
    命名之法 —— 时间、季节、地点
    文言的理解 —— 古时的称谓、别称、别名
    文言的理解 —— 古时的称谓、别称、别名
    Oracle GoldenGate for Oracle 11g to PostgreSQL 9.2.4 Configuration
    瀑布 敏捷 文档
    POJ 1325 ZOJ 1364 最小覆盖点集
  • 原文地址:https://www.cnblogs.com/Randolph68706/p/11226249.html
Copyright © 2011-2022 走看看