HDU 1281 board game (Bipartite Graph Matching)
Idea: Create a graph model for a classic bipartite graph. For each grid, create a column according to the row label, create a column, and then perform matching. Then, try to delete each edge, then, check whether the matching is smaller than the original match.
For details, see the code:
#include
#include
#include#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define Max(a,b) ((a)>(b)?(a):(b))#define Min(a,b) ((a)<(b)?(a):(b))using namespace std;typedef long long ll;typedef long double ld;const ld eps = 1e-9, PI = 3.1415926535897932384626433832795;const int mod = 1000000000 + 7;const int INF = 0x3f3f3f3f;// & 0x7FFFFFFFconst int seed = 131;const ll INF64 = ll(1e18);const int maxn = 100 + 10;int T,n,m,k,tot,kase = 0;int use[maxn],from[maxn];bool mp[maxn][maxn];bool match(int x) { for(int i = 1; i <= m; i++) if(!use[i] && mp[x][i]) { use[i] = true; if(from[i] == -1 || match(from[i])) { from[i] = x; return true; } } return false;}int hungary(int n) { tot = 0; memset(from, -1, sizeof(from)); for(int i = 1; i <= n; i++) { memset(use, 0, sizeof(use)); if(match(i)) ++tot; } return tot;}struct node { int r, c;}a[maxn*maxn];int main() { while(~scanf("%d%d%d",&n,&m,&k)) { memset(mp, false, sizeof(mp)); for(int i = 0; i < k; i++) { scanf("%d%d",&a[i].r,&a[i].c); mp[a[i].r][a[i].c] = true; } int init = hungary(n), ans = 0; for(int i = 0; i < k; i++) { mp[a[i].r][a[i].c] = false; int cur = hungary(n); mp[a[i].r][a[i].c] = true; if(cur < init) ++ans; } printf("Board %d have %d important blanks for %d chessmen.\n",++kase,ans,init); } return 0;}