zoukankan      html  css  js  c++  java
  • HDU1281 棋盘游戏

      行和列构成二分图,对于某个位置[x, y],如果可以放“车”,那么行x和列y连一条有向线 x -> y (g[x][y] = 1),在进行二分图匹配的时候,如果该某位置的连线算入了最大匹配中,根据最大匹配的定义知该位置所在的行和列肯定被屏蔽掉(不会进入最大匹配中)。那么有:

      能放的棋子数 L 即为最大匹配;而要计算某个点是否为重要点,只需要将该点连线去掉,计算最大匹配,如果此时计算得到的最大匹配小于原最大匹配,那么该点为重要点,这是我们枚举所有可放棋子点即可。

    View Code
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <map>
     4 using namespace std;
     5 
     6 const int maxn = 100 + 5;
     7 
     8 int n, m, k;
     9 bool g[maxn][maxn];
    10 bool vis[maxn];
    11 int link[maxn];
    12 int X[maxn * maxn], Y[maxn * maxn];
    13 
    14 bool find(int i)
    15 {
    16     for(int j = 1; j <= m; j ++)
    17     {
    18         if(g[i][j] && !vis[j])
    19         {
    20             vis[j] = true;
    21             if(!link[j] || find(link[j]))
    22             {
    23                 link[j] = i;
    24                 return true;
    25             }
    26         }
    27     }
    28     return false;
    29 }
    30 
    31 int main()
    32 {
    33     int x, y, t = 1;
    34     while(scanf("%d%d%d", &n, &m, &k) == 3)
    35     {
    36         memset(g, 0, sizeof g);
    37         for(int i = 0; i < k; i ++)
    38         {
    39             scanf("%d%d", &x, &y);
    40             g[x][y] = true;
    41             X[i] = x, Y[i] = y;
    42         }
    43         memset(link, 0, sizeof link);
    44         int res = 0;
    45         for(int i = 1; i <= n; i ++)
    46         {
    47             memset(vis, false, sizeof vis);
    48             res += find(i);
    49         }
    50         int cnt = 0;
    51         for(int i = 0; i < k; i ++)
    52         {
    53             g[X[i]][Y[i]] = false;
    54             memset(link, 0, sizeof link);
    55             int tmp = 0;
    56             for(int j = 1; j <= n; j ++)
    57             {
    58                 memset(vis, false, sizeof vis);
    59                 tmp += find(j);
    60             }
    61             g[X[i]][Y[i]] = true;
    62             cnt += (tmp < res);
    63         }
    64         printf("Board %d have %d important blanks for %d chessmen.\n", t++, cnt, res);
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    PDIUSBD12指令
    (转)USB的VID和PID,以及分类(Class,SubClass,Protocol)
    静态测试
    一种循环buffer结构
    RL78 芯片复位指令
    XModem协议
    位反转的最佳算法
    CCP 协议
    AUTOSAR 架构
    HEX 文件格式
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/2862671.html
Copyright © 2011-2022 走看看