hdu 1281 棋盘游戏
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1281
本题为简单最小点覆盖。只需先求出最小点覆盖然后枚举所有的点。
#include<stdio.h> #include<string.h> #define maxn 105 bool map[maxn][maxn],vis[maxn]; int n,m,k,mark[maxn],edge[maxn*maxn][2]; bool dfs(int v) { for(int i = 1; i <= m; i++) { if(vis[i] || !map[i][v]) continue; vis[i] = true; if(mark[i] == 0|| dfs(mark[i])) { mark[i] = v; return true; } } return false; } int Hungarian() {//匈牙利算法求二分图的最大匹配 int count = 0; memset(mark,0,sizeof(mark)); for(int i = 1; i <= n; i++) { memset(vis,false,sizeof(vis)); if(dfs(i)) count ++; } return count; } int main() { int i,sum,num = 1; while(scanf("%d%d%d",&n,&m,&k) != EOF) { memset(map,false,sizeof(map)); for(i = 0; i < k; i++) { scanf("%d%d",&edge[i][0],&edge[i][1]); map[edge[i][0]][edge[i][1]] = true; } int max ; //求最小点覆盖 max = Hungarian(); //枚举所有的点。 for(i = sum = 0; i < k; i++) { map[edge[i][0]][edge[i][1]] = false; if(max > Hungarian()) sum ++; map[edge[i][0]][edge[i][1]] = true; } printf("Board %d have %d important blanks for %d chessmen.\n",num++,sum,max); } return 0; }