HDU-1281 棋盘游戏 (二分图最大匹配)
思路:给你一个棋盘,给出障碍物。你需要在棋盘上摆放尽可能多的车(象棋)
然后求出棋盘中有多少位置 如果不摆放会使最大摆放数目减小
思路:我们从 HDU-1045 Fire Net 中知道可以对棋盘进行处理成二分图的形式
然后求出其最大匹配,同时我们也知道,棋子的位置(i,j)被处理成了二分图中的边
所以要求出影响最大摆放数目的关键位置,就是尝试减少某条边,然后判断最大匹配是否减小
然后题中的格子不能摆放不是前面 中墙的意思,只是单存的不能放。
完整代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int maxn = 1e4+5; int G[105][105]; int a[maxn],b[maxn]; int match[105]; int vis[105]; int n,m,ans; bool Find(int u){ for(int i = 1;i<=m;i++){ if(!vis[i]&&G[u][i]){ vis[i] = 1; if(!match[i]||Find(match[i])){ match[i] = u; return true; } } } return false; } int Count(){ int count = 0; memset(match,0,sizeof(match)); for(int i =0;i<=n;i++){ memset(vis,0,sizeof(vis)); if(Find(i)) count++; } return count; } int main(){ int k; int Case = 0; while(cin>>n>>m>>k){ memset(G,0,sizeof(G)); for(int i = 0;i<k;i++){ cin>>a[i]>>b[i]; G[a[i]][b[i]] = 1; } ans = 0; int num = Count(); for(int i =0;i<k;i++){ G[a[i]][b[i]] = 0; if(Count()<num) ans++; G[a[i]][b[i]] = 1; } printf("Board %d have %d important blanks for %d chessmen.\n",++Case,ans,num); } }