zoukankan      html  css  js  c++  java
  • Codevs1922 骑士共存问题

    1922 骑士共存问题

    题目描述 Description

    在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘
    上某些方格设置了障碍,骑士不得进入。

     

    对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑
    士,使得它们彼此互不攻击。

    输入描述 Input Description

    第一行有2 个正整数n 和m (1<=n<=200, 0<=m<n^2),
    分别表示棋盘的大小和障碍数。接下来的m 行给出障碍的位置。每行2 个正整数,表示障
    碍的方格坐标。

    输出描述 Output Description

    将计算出的共存骑士数输出

    样例输入 Sample Input

    3 2

    1 1

    3 3

    样例输出 Sample Output

    5

    数据范围及提示 Data Size & Hint

    详见试题

    【题解】

    卡了半天常还是卡不过去,等以后再用Dinic写吧

    先进行黑白染色(此类问题常用),不难发现骑士

    只会从黑->白或白->黑,因此我们令X集合为黑,

    Y集合为白,从黑->白则连一条边(给黑白格子编 号),

    然后找最大独立集即可。注意总的节点数 是没有障碍的

    点,做最大匹配的时候也要用没有 障碍的格子的染色

    编号。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 
     6 inline void read(int &x)
     7 {
     8     x = 0;char ch = getchar(), c = ch;
     9     while(ch < '0' || ch > '9') c = ch, ch = getchar();
    10     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    11     if(c == '-')x = -x;
    12 }
    13 
    14 const int MAXN = 200 + 10;
    15 const int dx[8] = {1,-1,2,-2,1,-1,2,-2};
    16 const int dy[8] = {2,-2,1,-1,-2,2,-1,1};
    17 
    18 int gg[MAXN][MAXN], b[MAXN][MAXN], n, m, lk[200000],bb[200000];
    19 
    20 struct Edge
    21 {
    22     int u,v,next;
    23     Edge(int _u, int _v, int _next){u = _u;v = _v;next = _next;}
    24     Edge(){}
    25 }edge[200000];
    26 
    27 int head[200000];
    28 
    29 int dfs(int u)
    30 {
    31     for(int pos = head[u];pos;pos = edge[pos].next)
    32     {
    33         int v = edge[pos].v;
    34         if(bb[v])continue;
    35         bb[v] = 1;
    36         if(lk[v] == -1 || dfs(lk[v]))
    37         {
    38             lk[v] = u;
    39             return 1;
    40         }
    41     }
    42     return 0;
    43 }
    44 
    45 int xiongyali(int white)
    46 {
    47     int ans = 0;
    48     memset(lk, -1, sizeof(lk));
    49     for(register int i = 1;i <= white;++i)
    50     {
    51         memset(bb, 0, sizeof(bb));
    52         ans += dfs(i);
    53     }
    54     return ans;
    55 }
    56 
    57 int main()
    58 {
    59     read(n), read(m);
    60     register int black, white, i;
    61     for(i = 1;i <= m;++ i)
    62     {
    63         read(black), read(white);
    64         b[black][white] = 1;
    65     }
    66     //X集合:1 白色  Y集合:0 黑色 
    67     black = white = 0;
    68     for(i = 1;i <= n;++ i)
    69         for(int j = 1;j <= n;++ j)
    70             if(!b[i][j])
    71                 if((i + j)&1) gg[i][j] = ++ black;
    72                 else gg[i][j] = ++ white;
    73     register int xx, yy, cnt = 0;
    74     for(i = 1;i <= n;++ i)
    75         for(int j = 1;j <= n;++ j)
    76             if(!((i + j)&1) && !b[i][j])
    77                 for(int k = 0;k < 8;++ k)
    78                 {
    79                     xx = i + dx[k], yy = j + dy[k];
    80                     if(xx <= 0 || yy <= 0 || xx > n || yy > n || b[xx][yy])continue;
    81                     yy = gg[xx][yy], xx = gg[i][j];
    82                     edge[++cnt] = Edge(xx,yy,head[xx]);
    83                     head[xx] = cnt;
    84                 }
    85     printf("%d", white + black - xiongyali(white));
    86     return 0;
    87 }
    90分TLE代码
  • 相关阅读:
    删数问题
    八中公司_二分图带权最大匹配模板题
    完美子图(这道题太难了,得写下来要不回头又忘了)
    最近集训的图论(思路+实现)题目汇总(内容包含tarjan、分层图、拓扑、差分、奇怪的最短路):
    方格取数(简单版)+小烈送菜(不知道哪来的题)-----------奇怪的dp增加了!
    单调队列优化题:最大数(P1198)
    单调队列+线性dp题Watching Fireworks is Fun (CF372C)
    关于看了几道洛谷灰题(暂无评定)的感想
    洛谷的奇妙今日运势
    互不侵犯(洛谷P1896)
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7582521.html
Copyright © 2011-2022 走看看