棋盘游戏

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7898    Accepted Submission(s): 4600

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.
 
Author
Gardon
 
Source
 
Recommend
lcy
 
 /*************************************************************************
> File Name: hdu-1281.棋盘游戏.cpp
> Author: CruelKing
> Mail: 2016586625@qq.com
> Created Time: 2019年08月28日 星期三 09时49分22秒
本题思路:本题的重点在于如何求解重要边,最简单的思路就是枚举所有边,如果去掉一条边之后发现最大匹配数目减少了,则说明这条边所对应的点就是关键点。
其次还有一种复杂度更低的思路,就是对于每个已经匹配过的边,先删除这条边,我们以所有没有匹配过的顶点为起点再去匹配边,如果发现可以匹配到那么就说明还可以找到其他增广路,意思就是可以有别的匹配边代替这条匹配边,那么这个点就不是关键点,否则这个点就是关键点。
************************************************************************/
/*
#include <cstdio>
#include <cstring>
using namespace std; const int maxn = 100 + 5, maxm = 100 * 100 + 5;
int linker[maxn], ui[maxn], vi[maxn];
bool used[maxn], g[maxn][maxn];
int n, m; bool dfs(int u) {
for(int v = 1; v <= m; v ++) {
if(g[u][v] && !used[v]) {
used[v] = true;
if(linker[v] == -1 || dfs(linker[v])) {
linker[v] = u;
return true;
}
}
}
return false;
} int hungary() {
int res = 0;
memset(linker, -1, sizeof linker);
for(int i = 1; i <= n; i ++) {
memset(used, false, sizeof used);
if(dfs(i)) res ++;
}
return res;
} int main() {
int k, u, v, Case = 0;
while(~scanf("%d %d %d", &n, &m, &k)) {
memset(g, false, sizeof g);
for(int i = 0; i < k; i ++) {
scanf("%d %d", &ui[i], &vi[i]);
g[ui[i]][vi[i]] = true;
}
int res1 = hungary(), cnt = 0;
for(int i = 0; i < k; i ++) {
g[ui[i]][vi[i]] = false;
int res2 = hungary();
if(res2 < res1) cnt ++;
g[ui[i]][vi[i]] = true;
}
printf("Board %d have %d important blanks for %d chessmen.\n", ++ Case, cnt, res1);
}
return 0;
}
*/ #include <cstdio>
#include <cstring>
using namespace std; const int maxn = + ;
int n, m, k;
int linkery[maxn], linkerx[maxn];
bool used[maxn], g[maxn][maxn];
bool flag; bool dfs(int u) {
for(int v = ; v <= m; v ++) {
if(g[u][v] && !used[v]) {
used[v] = true;
if(linkery[v] == - || dfs(linkery[v])) {
if(flag) {
linkery[v] = u;
linkerx[u] = v;
}
return true;
}
}
}
return false;
} int hungary() {
flag = true;
memset(linkery, -, sizeof linkery);
memset(linkerx, -, sizeof linkerx);
int res = ;
for(int i = ; i <= n; i ++) {
memset(used, false, sizeof used);
if(dfs(i)) res ++;
}
return res;
} bool can() {
flag = false;
for(int u = ; u <= n; u ++) {
if(linkerx[u] == -) {
memset(used, false, sizeof used);
if(dfs(u)) return true;
}
}
return false;
} int main() {
int u, v, Case = ;
while(~scanf("%d %d %d", &n, &m, &k)) {
memset(g, false, sizeof g);
for(int i = ; i < k; i ++) {
scanf("%d %d", &u, &v);
g[u][v] = true;
}
int ans = hungary();
int res = , temp;
for(int i = ; i <= n; i ++) {
if(~linkerx[i]) {
temp = linkerx[i];
linkerx[i] = linkery[temp] = -;
g[i][temp] = false;
if(!can()) res ++;
linkerx[i] = temp;
linkery[temp] = i;
g[i][temp] = true;
}
}
printf("Board %d have %d important blanks for %d chessmen.\n", ++ Case, res, ans);
}
return ;
}

hdu-1281.棋盘游戏(二分图匹配 + 二分图关键点查询)的更多相关文章

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

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

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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281   Problem Description 小希和Gardon在玩一个游戏:对一个N*M的棋盘, ...

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

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

  4. hdu 1281 棋盘游戏

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

  5. HDU——1281 棋盘游戏

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

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

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

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

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

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

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

  9. HDU 1281 - 棋盘游戏 - [二分图最大匹配]

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1281 Time Limit: 2000/1000 MS (Java/Others) Mem ...

随机推荐

  1. 【leetcode】491. Increasing Subsequences

    题目如下: 解题思路:这题把我折腾了很久,一直没找到很合适的方法,主要是因为有重复的数字导致结果会有重复.最后尝试用字典记录满足条件的序列,保证不重复,居然Accept了. 代码如下: class S ...

  2. 对Nuxt的研究

    Nuxt就是基于Vue的一个应用框架,采用服务端渲染,让你的SPA应用(Vue)也可以拥有SEO Nuxt的生命周期有些在服务端(Node),客户端,甚至两边都在: 1.其他之前都不存在Window对 ...

  3. git初步研究2

    $git init Git 使用 git init 命令来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行,所以 git init 是使用 Git 的第一个命令. 在执行完成 ...

  4. Quantitative Startegies for Achieving Alpha(二)

    Chapter 3 The Day-To-Day Drivers Of Stock Market Returns Summary: (1) Earning growth is the primary ...

  5. 简单说说JavaBean的使用

    一:JavaBean定义 JavaBean是一种可重复使用.跨平台的软件组件.JavaBean可分为两种:一种是有用户界面(UI,User Interface)的JavaBean,例如中的那些可视化图 ...

  6. Spring——IOC与Bean容器

    [IOC] (1)IOC:控制反转,控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器负责创建和维护.也就是说由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中 (2)DI: ...

  7. 走进JavaWeb技术世界14:Mybatis入门

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  8. Linux shell - 按时间和文件大小排序显示文件(ll)

    在工作中有这样的情况,需要显示所有的文件,按照时间先后或者文件大小先后排序显示 命令:ls 1.按时间排序显示文件 test@> ll -rt 2.按文件大小排序显示文件(文件大小单位:k,M) ...

  9. gsxt滑动验证码

    最后,谈谈滑动验证码. 目前,工商网站已经全面改版,全部采用了滑动验证码,上面绝大多数思路都失效了.对于滑动验证码,网上能搜到的解决方案基本都是下载图片,还原图片,算出滑动距离,然后模拟js来进行拖动 ...

  10. Android animation summary

    Android animation 动画定义 动画的意思就是一连串画面动起来了,根据这一连串画面的产生原理可分为两类:补间动画(Tween animation)和帧动画(frame animation ...