Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 852 Accepted Submission(s): 492
3 3 4 1 2 1 3 2 1 2 2 3 3 4 1 2 1 3 2 1 3 2
Board 1 have 0 important blanks for 2 chessmen. Board 2 have 3 important blanks for 3 chessmen.
#include <iostream> #include <stdio.h> #include <memory.h> using namespace std; const int N = 105; bool map[N][N], flag[N]; int pre[N], c[N*N][2]; int n, m, k; int find(int cur) //匈牙利算法(二分匹配) { int i; for(i = 1; i <= m; i++) { if(map[cur][i] && !flag[i]) { flag[i] = true; if(pre[i] == -1 || find(pre[i])) { pre[i] = cur; return 1; } } } return 0; } int run() { int i, sum = 0; memset(pre, -1, sizeof(pre)); for(i = 1; i <= n; i++) { memset(flag, false, sizeof(flag)); sum += find(i); } return sum; } int main() { int i, x, y, sum, ans, num, zz = 1; while(scanf("%d %d %d", &n, &m, &k) != EOF) { memset(map, false, sizeof(map)); memset(c, 0, sizeof(c)); for(i = 1; i <= k; i++) { scanf("%d %d", &x, &y); map[x][y] = true; //建图 c[i][0] = x; //行 c[i][1] = y; //列 } sum = run(); ans = 0; for(i = 1; i <= k; i++) //分别枚举每条边(x,y) { map[ c[i][0] ][ c[i][1] ] = false; num = run(); if(num < sum) ans++; //比sum少,证明那条边关键点(x,y) map[ c[i][0] ][ c[i][1] ] = true; } printf("Board %d have %d important blanks for %d chessmen.\n", zz++, ans, sum); } return 0; }