zoukankan      html  css  js  c++  java
  • POJ_2446_Chessboard

    题意:给出一个m*n的矩阵,其中有的地方有坑,然后用1*2的纸片去覆盖图,纸片不能重复,能够把出了坑的地方其他全部覆盖的话输出YES,否则NO。

    分析:按其奇偶性建图的,因为要用1*2的纸片覆盖,那么两个值(i+j)必然一个奇数一个偶数,然后分别给图中的奇数偶数点依次从1开始标号,相邻的按其标号建图,匈牙利。因为必然是一个奇数点对应一个相邻偶数点,那么只要求任意奇数或偶数的最大匹配就可以了。

    总结:二分图的第一道题,了解了匈牙利算法,对dfs实现匈牙利算法还不熟悉(不能熟练写出递归程序,长期以来的问题)。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define Del(x,y) memset(x,y,sizeof(x))
    
    int path[33][33],map[600][600],vis[600],link[600];
    int cnt1,cnt2,m,n,k;
    
    int dfs(int x)
    {
        for(int i=1; i<=cnt2; i++)
            if(map[x][i]==1)
                if(vis[i]==0)
                {
                    vis[i]=1;
                    if(link[i]==-1||dfs(link[i]))
                    {
                        link[i]=x;
                        return 1;
                    }
                }
        return 0;
    }
    
    void solve()
    {
        int ans=0;
        Del(link,-1);
    
        for(int i=1; i<=cnt1; i++)
        {
            Del(vis,0);
            if(dfs(i))
                ans++;
        }
        //printf("%d
    ",ans);
        if((ans*2)==(n*m-k))
            printf("YES
    ");
        else
            printf("NO
    ");
    }
    int main()
    {
        int x,y;
        scanf("%d%d%d",&m,&n,&k);
        Del(path,0);
        for(int i=0;i<k;i++)
        {
            scanf("%d%d",&x,&y);
            path[y][x]=-1;
        }
        cnt1=1,cnt2=1;
        for(int i=1; i<=m; i++)
            for(int j=1; j<=n; j++)
            {
                if(path[i][j]==0)
                {
                    if((i+j)%2==1)
                        path[i][j]=cnt1++;
                    else
                        path[i][j]=cnt2++;
                }
            }
            cnt1--;cnt2--;
        Del(map,0);
        for(int i=1; i<=m; i++)
            for(int j=1; j<=n; j++)
                if(path[i][j]!=-1&&(i+j)%2==1)
                {
                    if(path[i-1][j]>0)
                        map[path[i-1][j]][path[i][j]]=1;
                    if(path[i+1][j]>0)
                        map[path[i+1][j]][path[i][j]]=1;
                    if(path[i][j-1]>0)
                        map[path[i][j-1]][path[i][j]]=1;
                    if(path[i][j+1]>0)
                        map[path[i][j+1]][path[i][j]]=1;
                }
        solve();
        return 0;
    }
  • 相关阅读:
    2018第九届蓝桥杯C/C++ B国赛 —— 第三题:格雷码
    数据结构和算法 —— 谈谈算法
    数据结构和算法 —— 谈谈算法
    数据结构和算法 —— 绪论
    数据结构和算法 —— 绪论
    2018第九届蓝桥杯C/C++ B国赛 —— 第二题:激光样式
    2018第九届蓝桥杯C/C++ B国赛 —— 第二题:激光样式
    2018第九届蓝桥杯C/C++ B国赛 —— 第一题:换零钞
    围棋
    恶搞造句
  • 原文地址:https://www.cnblogs.com/jasonlixuetao/p/4755574.html
Copyright © 2011-2022 走看看