zoukankan      html  css  js  c++  java
  • POJ2446 模板盖格子 简单二分匹配

    题意:
          给你一个n*m的格子,有的格子上有坑,然后让你用1*2的东西去覆盖所有没有坑的格子,不能重叠,坑上也不能放东西覆盖,问是否能成功。


    思路: 
          简单题目,每个格子和四周的格子如果可以放在同一个1*2的里面那么就连接一条边,直接匹配一遍就行了,有的人可能想问为什么?可以这么想,首先如果像覆盖所有的格子那么必须是放最多的1*2覆盖物((n*m-k)/2这么多个),然后每个覆盖物会覆盖两个,也就是说必须这写覆盖物最后覆盖的都是一对一对的,把所有的点都拆成两个点,左右各一排,然后直接匹配,最后/2是不是就是能覆盖的最大的对数?so.....




    #include<stdio.h>
    #include<string.h>


    #define N_node 1500
    #define N_edge 6000


    typedef struct
    {
        int to ,next;
    }STAR;


    STAR E[N_edge];
    int list[N_node] ,tot;
    int mkgx[N_node] ,mkdfs[N_node];
    int map[32+5][32+5];


    void add(int a ,int b)
    {
        E[++tot].to = b;
        E[tot].next = list[a];
        list[a] = tot;
    }


    int DFS_XYL(int x)
    {
        for(int k = list[x] ;k ;k = E[k].next)
        {
            int to = E[k].to;
            if(mkdfs[to]) continue;
            mkdfs[to] = 1;
            if(mkgx[to] == -1 || DFS_XYL(mkgx[to]))
            {
                mkgx[to] = x;
                return 1;
            }
        }
        return 0;
    }




    int main ()
    {
        int n ,m ,q;
        int a ,b ,i ,j;
        while(~scanf("%d %d %d" ,&n ,&m ,&q))
        {
            memset(map ,0 ,sizeof(map));
            for(i = 1 ;i <= q ;i ++)
            {
                scanf("%d %d" ,&a ,&b);
                map[b][a] = 1;
            }
            
            if((n * m - q)&1)
            {
                printf("NO ");
                continue;
            }
            memset(list ,0 ,sizeof(list));
            tot = 1;
            for(i = 1 ;i <= n ;i ++)
            for(j = 1 ;j <= m ;j ++)
            {
                if(map[i][j]) continue;
                if(i <= n - 1 && !map[i+1][j])
                add((i - 1) * m + j ,i * m + j);
                if(j <= m - 1 && !map[i][j+1])
                add((i - 1) * m + j ,(i - 1) * m + j + 1);
                if(i >= 2 && !map[i-1][j])
                add((i - 1) * m + j ,(i - 2) * m + j);
                if(j >= 2 && !map[i][j-1])
                add((i - 1) * m + j ,(i - 1) * m + j - 1);
            }
            memset(mkgx ,255 ,sizeof(mkgx));
            int ans = 0;
            for(i = 1 ;i <= n * m ;i ++)
            {
                memset(mkdfs ,0 ,sizeof(mkdfs));
                ans += DFS_XYL(i);
            }
            if(ans == n * m - q)
            printf("YES ");
            else printf("NO ");
        }
        return 0;
    }







  • 相关阅读:
    2017-2018-1 20155337《信息安全系统设计基础》第6周学习总结
    # 2017-2018-1 20155337《信息安全系统设计基础》第5周学习总结+mybash
    # 2017-2018-3 20155337《信息安全系统设计基础》第4周学习总结
    # 2017-2018-3 20155337《信息安全系统设计基础》第3周学习总结
    # 20155337 2017-2018-1 《信息安全系统设计基础》第二周课堂实践+myod
    # 20155337 2017-2018-1 《信息安全系统设计基础》第一周学习总结
    2017-2018-1 20155317《信息安全系统设计基础》第八周学习总结
    20155317 第八周课下作业(2)
    20155317 第八周课下作业(1)
    实验二20155324 20155317 实验报告 固件程序设计
  • 原文地址:https://www.cnblogs.com/csnd/p/12062501.html
Copyright © 2011-2022 走看看