二分图匹配——棋盘游戏 ( HDU 1281 )
2016-07-18 10:17
274 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1281
分析&题解:
题意是求最多可以放几个棋子,并且哪几个点是必须放子的,一看就是二分图匹配,匹配行和列,最后,搜索所有边,每次删除一条边,如果最大匹配变少了,这条边(就是棋盘位置)就是关键位置。
AC代码:
http://acm.hdu.edu.cn/showproblem.php?pid=1281
分析&题解:
题意是求最多可以放几个棋子,并且哪几个点是必须放子的,一看就是二分图匹配,匹配行和列,最后,搜索所有边,每次删除一条边,如果最大匹配变少了,这条边(就是棋盘位置)就是关键位置。
AC代码:
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> using namespace std; int Map[110][110]; int mark[110]; int flag[110]; int N,M,K; int n; bool DFS(int x) { for(int i=1;i<=M;i++) { if(!Map[x][i] || flag[i]) continue; flag[i] = 1; if(!mark[i] || DFS(mark[i])) { mark[i] = x; return 1; } } return 0; } int Hungarian() { int ans = 0; memset(mark, 0, sizeof(mark)); for(int i=1;i<=N;i++) { memset(flag, 0, sizeof(flag)); if(DFS(i)) { ans++; } } return ans; } int main() { int t = 1; while(cin >> N >> M >> K) { memset(Map,0,sizeof(Map)); n = max(N,M); for(int i=0;i<K;i++) { int x,y; cin >> x >> y; Map[x][y] = 1; } int Ans = Hungarian(); int VIP = 0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(Map[i][j]) { Map[i][j] = 0; if(Hungarian() != Ans) VIP++; Map[i][j] = 1; } } } cout << "Board " << t++ <<" have " << VIP << " important blanks for " << Ans << " chessmen." << endl; } }
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACMer博客瀑布流分析
- ACM程序设计大赛题目分类
- 2015年acm国内排名
- 计算字符串最后一个单词长度
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1002