题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1281

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Problem Description
小希和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.
 
题解:
参考http://www.cnblogs.com/dilthey/p/7647870.html博文中的方法②;
因为这次没有墙能隔开车与车之间的攻击,故直接将整行整列缩成点,然后求出max match;
但是如何寻找其中的“必须边”呢?
比较好想的方法就是直接暴力枚举最大匹配中的匹配边,如果把它去掉还能不能得到一样的最大匹配数:
如果不能,就是必须边,cnt+=1;
 
AC代码:
 #include<cstdio>
#include<cstring>
#include<vector>
#define MAX 203
using namespace std;
int n,m,k;
int edge[MAX][MAX];
int matching[MAX];
int vis[MAX];
void init(){memset(edge,,sizeof(edge));}
void add_edge(int u,int v){edge[u][v]=edge[v][u]=;}
bool dfs(int u)
{
for(int v=;v<=n+m;v++)
{
if(!edge[u][v]) continue;
if (!vis[v])
{
vis[v]=;
if(!matching[v] || dfs(matching[v]))
{
matching[v]=u;
matching[u]=v;
return true;
}
}
}
return false;
}
int hungarian()
{
int ret=;
memset(matching,,sizeof(matching));
for(int i=;i<=n;i++)
{
if(!matching[i])
{
memset(vis,,sizeof(vis));
if(dfs(i)) ret++;
}
}
return ret;
}
int mp[][],match[MAX][MAX];
int main()
{
int kase=;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
memset(mp,,sizeof(mp));
for(int i=,r,c;i<=k;i++)
{
scanf("%d%d",&r,&c);
mp[r][c]=;
} init();
for(int i=;i<=n;i++) for(int j=;j<=m;j++) if(mp[i][j]) add_edge(i,j+n);
int max_match=hungarian(); int cnt=;
memset(match,,sizeof(match));
for(int i=;i<=n+m;i++) for(int j=n+;j<=n+m;j++) if(matching[i]==j && matching[j]==i) match[i][j]=;
for(int i=;i<=n+m;i++)
{
for(int j=n+;j<=n+m;j++)
{
if(match[i][j])
{
edge[i][j]=;
if(hungarian()<max_match) cnt++;
edge[i][j]=;
}
}
} printf("Board %d have %d important blanks for %d chessmen.\n",++kase,cnt,max_match);
}
}

HDU 1281 - 棋盘游戏 - [二分图最大匹配]的更多相关文章

  1. HDU 1281——棋盘游戏——————【最大匹配、枚举删点、邻接表方式】

     棋盘游戏 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status ...

  2. (step6.3.5)hdu 1281(棋盘游戏——二分图的完美匹配)

    题目大意:本体是中文题.读者可以直接在OJ上看 解题思路: 1)完美匹配:所有的端点都是匹配点 2)对于二分图的完美匹配,我们需要用一个数组来存储匹配点.(而二分图的其他问题(我们则可以直接使用变量来 ...

  3. HDU 1281 棋盘游戏 (枚举+最大匹配)

    <题目链接> Problem Description 小希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,这当然很简单 ...

  4. hdu 1281 棋盘游戏(二分图)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281 每行每列作为节点,给可以放车的点将对应的行列连边,最多可放置的车即为建二分图后的最大匹配,跑一边 ...

  5. hdu 1281 棋盘游戏

    http://acm.hdu.edu.cn/showproblem.php?pid=1281 棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  6. hdu 1281 棋盘游戏(二分匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281 棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    M ...

  7. HDU 1281 棋盘游戏 【二分图最大匹配】

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1281 题意概括: 有N*M大的棋盘,要在里面放尽量多的“车”,求最多能放的车的个数,和为了放最多的车有多 ...

  8. D - 棋盘游戏 - HDU 1281(二分图匹配)

    分析:先求出来最大匹配数,然后用匹配的点一个一个去除看看能否达到最大匹配,能的话就是关键点(很暴力啊),不过竟然才31ms ************************************** ...

  9. hdu 1281 棋盘游戏 (二分匹配)

    棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

随机推荐

  1. iOS: 解决某些第三方库因为ARC不能使用的问题

    1.在target下面的build phases下有一个compile source,下面有很多待编译文件.可以看到一个compile flag,可以针对某些文件进行arc设置.这样,某些框架不能使用 ...

  2. 开源一个简易轻量的reactor网络框架

    github https://github.com/sea-boat/net-reactor net-reactor it's a simple and easy net framework with ...

  3. swift--CATransform3D的简单介绍

    今天来了解下CATransform3D的一些基本的知识.CATransform3D是一个用于处理3D形变的类,其可以改变控件的平移.缩放.旋转.斜交等,其坐标系统采用的是三维坐标系,即向右为x轴正方向 ...

  4. iOS 使用动态库

    苹果的开放态度 WWDC2014上发布的Xcode6 beta版有了不少更新,其中令我惊讶的一个是苹果在iOS上开放了动态库,在Xcode6 Beta版的更新文档中是这样描述的: Frameworks ...

  5. 【Cesium】模型转换和使用(转)

    http://52.4.31.236/convertmodel.html https://blog.csdn.net/UmGsoil/article/details/74572877 var view ...

  6. ZooKeeper 未授权访问漏洞

    ZooKeeper 安装: Zookeeper的默认开放端口是2181 wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zooke ...

  7. 【RF库测试】set variable if

  8. Ansible Playbook 使用变量

    如何在 Playbook 中定义并使用变量: vars: - user: "test" # 定义变量 tasks: - name: create user user: name=& ...

  9. CMake设置输出目录

    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Lib)set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAK ...

  10. [Command] wc

    wc 命令可以打印目标文件的换行.单词和字节数.其中换行数 = 总行数 - 1,单词数则按照空格分隔的英文单词数进行统计,也就是说连续的汉字(短语.句子)都视作一个单词. NAME wc - 打印每个 ...