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

    小希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,这当然很简单,但是Gardon限制了只有某些格子才可以放,小希还是很轻松的解决了这个问题(见下图)注意不能放车的地方不影响车的互相攻击。 
    所以现在Gardon想让小希来解决一个更难的问题,在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下。但是某些格子若不放子,就无法保证放尽量多的“车”,这样的格子被称做重要点。Gardon想让小希算出有多少个这样的重要点,你能解决这个问题么? 

    Input输入包含多组数据, 
    第一行有三个数N、M、K(1<N,M<=100 1<K<=N*M),表示了棋盘的高、宽,以及可以放“车”的格子数目。接下来的K行描述了所有格子的信息:每行两个数X和Y,表示了这个格子在棋盘中的位置。 
    Output对输入的每组数据,按照如下格式输出: 
    Board T have C important blanks for L chessmen. 
    Sample Input

    3 3 4
    1 2
    1 3
    2 1
    2 2
    3 3 4
    1 2
    1 3
    2 1
    3 2

    Sample Output

    Board 1 have 0 important blanks for 2 chessmen.
    Board 2 have 3 important blanks for 3 chessmen.
    题解:
    我们可以经横坐标,纵坐标当成两个集合,即可转化为二分图的最大匹配问题;模板题
    对于中重要点,我们可以依次去掉匹配中的点,如果最大匹配数不变,则不是重要点,如果最大匹配数变少,这是重要点(和以前做的一道最小生成树的唯一性判断方法类似,)
    参考代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=105;
     4 int n,m,k,ok[maxn];
     5 bool a[maxn][maxn],vis[maxn];
     6 
     7 bool Find(int x)
     8 {
     9     for(int i=1;i<=m;i++)
    10     {
    11         if(a[x][i]&&!vis[i])
    12         {
    13             vis[i]=true;
    14             if(!ok[i]||Find(ok[i]))
    15             {
    16                 ok[i]=x;
    17                 return true;
    18             }
    19         }
    20     }
    21     return false;
    22 }
    23 int maxP()
    24 {
    25     int ans=0;
    26     memset(ok,0,sizeof(ok));
    27     for(int i=1; i<=n; i++)
    28     {
    29         memset(vis,false,sizeof(vis));
    30         if(Find(i)) ans++;
    31     }
    32     return ans;
    33 }
    34 int main()
    35 {
    36     int kase=0;
    37     while(cin>>n>>m>>k)
    38     {
    39         memset(a,false,sizeof(a));
    40         int x,y,z;
    41         while(k--)
    42         {
    43             cin>>x>>y;
    44             a[x][y]=true;
    45         }
    46         int ans=maxP();
    47         int cnt=0;
    48         for(int i=1; i<=n; i++)
    49         {
    50             for(int j=1; j<=m; j++)
    51             {
    52                 if(a[i][j])
    53                 {
    54                     a[i][j]=false;
    55                     int t=maxP();
    56                     a[i][j]=true;
    57                     if(t<ans) cnt++;
    58                 }
    59             }
    60         }
    61         printf("Board %d have %d important blanks for %d chessmen.
    ",++kase,cnt,ans);
    62     }
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    [JSOI2007][BZOJ1031] 字符加密Cipher|后缀数组
    leetcode Flatten Binary Tree to Linked List
    leetcode Pascal's Triangle
    leetcode Triangle
    leetcode Valid Palindrome
    leetcode Word Ladder
    leetcode Longest Consecutive Sequence
    leetcode Sum Root to Leaf Numbers
    leetcode Clone Graph
    leetcode Evaluate Reverse Polish Notation
  • 原文地址:https://www.cnblogs.com/csushl/p/9520599.html
Copyright © 2011-2022 走看看