zoukankan      html  css  js  c++  java
  • hdu 4619 Warm up 2 (二分匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4619

    题意:

    平面上有一些1×2的骨牌,每张骨牌要么水平放置,要么竖直放置,并且保证同方向放置的骨牌不会相互覆盖。水平放置的牌和竖直放置的牌可能相互覆盖,现在要移去一些牌,使得剩下的牌任何两张都不会相互覆盖,问桌面上最多能剩多少张牌。

    分析:

    如果把每张牌看作一个结点,则共有两类结点,容易联想到二分图。另外,同方向的牌不会相互覆盖,不同方向的可能相互覆盖,易想到二分图的一个重要性质:同类结点间不会连边,不同结点间可以连边。所以显然是这方面的问题了。

    解题思路:

    根据上述分析,这是一个二分图问题,每张牌作为一个结点,水平放置的成点集X,竖直放置的成点集Y,若两张牌相互覆盖,则两点间连边。这样建图后,一个“覆盖点”对应一条边,成了裸的“最小点覆盖”问题,即:结点数-最大二分匹配数。

    代码:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define N 1200
    
    bool mp[N][N];
    int x[N], y[N], f[N], rm[N], lm[N];
    int n, m;
    
    bool path(int s)
    {
        for(int i = 1; i <= m; i++)
            if(f[i] == 0 && mp[s][i])
            {
                f[i] = 1;
                if(rm[i] == 0 || path(rm[i]))
                {
                    rm[i] = s; lm[s] = i;
                    return true;
                }
            }
        return false;
    }
    
    int MaxMatch()
    {
        memset(rm, 0, sizeof(rm));
        memset(lm, 0, sizeof(lm));
        int ans = 0;
        for(int i = 1; i <= n; i++)
        if(!lm[i])
        {
            memset(f, 0, sizeof(f));
            if(path(i)) ans++;
        }
        return ans;
    }
    int main()
    {
        int i, j;
        while(~scanf("%d %d", &n, &m), n||m)
        {
            int a, b;
            for(i = 1; i <= n; i++)
                scanf("%d %d", &x[i], &y[i]);
            memset(mp, false, sizeof(mp));
            for(i = 1; i <= m; i++)
            {
                scanf("%d %d", &a, &b);
                for(j = 1; j <= n; j++)
                if( (a == x[j] && b == y[j]) || 
                    (a == x[j] && b == y[j] - 1) || 
                    (a == x[j] + 1 && b == y[j]) || 
                    (a == x[j] + 1 && b == y[j]-1)
                ) mp[j][i] = true;
            }
            int ans = MaxMatch();
            printf("%d
    ", n+m-ans);
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    idea 将java导出为可执行jar及导入jar依赖
    使用idea 调试java -jar xxx.jar方式启动
    springboot 打成的jar包在ClassLoader().getResource方法读取文件为null
    maven 使用dependencyManagement统一管理依赖版本
    Win10系列:C#应用控件基础5
    Win10系列:C#应用控件基础4
    Win10系列:C#应用控件基础3
    Win10系列:C#应用控件基础2
    Win10系列:C#应用控件基础1
    Win10系列:UWP界面布局进阶9
  • 原文地址:https://www.cnblogs.com/beisong/p/4032919.html
Copyright © 2011-2022 走看看