Hdu 1281 棋盘游戏 (二分匹配)
题目链接:
题目描述:
题目汉语,只说一点,国际象棋中车的攻击范围就像n皇后问题中的皇后一样,同行和同列的车都会相互攻击。
解题思路:
求出来的最大匹配数目==最多能放几个车。计算有几个格子是重要点的时候只需要算出最大的匹配数目,然后枚举每个点不能放置棋子时候的最大匹配数目。最大匹配数目小于原匹配数目的时候,当前枚举点就是重要点。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 110; 8 int maps[maxn][maxn], ans[maxn], n, m, k; 9 int used[maxn], vis[maxn], p[2][maxn*maxn]; 10 11 bool Find (int x) 12 {//匈牙利算法 13 for (int i=1; i<=m; i++) 14 { 15 if (!vis[i] && maps[x][i]) 16 { 17 vis[i] = 1; 18 if (!used[i] || Find(used[i])) 19 { 20 used[i] = x; 21 return true; 22 } 23 } 24 } 25 return false; 26 } 27 int main () 28 { 29 int l = 0; 30 while (scanf ("%d %d %d", &n, &m, &k) != EOF) 31 { 32 p[0][0] = p[1][0] = 0; 33 p[0][k+1] = p[1][k+1] = 0; 34 memset (maps, 0, sizeof(maps)); 35 for (int i=1; i<=k; i++) 36 { 37 scanf ("%d %d", &p[0][i], &p[1][i]); 38 maps[p[0][i]][p[1][i]] = 1; 39 } 40 memset (ans, 0, sizeof(ans)); 41 int Max = 0; 42 for (int i=1; i<=k+1; i++) 43 {//枚举可放置棋子的点 44 maps[p[0][i-1]][p[1][i-1]] = 1; 45 maps[p[0][i]][p[1][i]] = 0; 46 int res = 0; 47 memset (used, 0, sizeof(used)); 48 for (int j=1; j<=n; j++) 49 { 50 memset (vis, 0, sizeof(vis)); 51 if (Find(j)) 52 res ++; 53 } 54 ans[res] ++; 55 if (res > Max) 56 Max = res; 57 } 58 printf ("Board %d have %d important blanks for %d chessmen.\n", ++l, k - ans[Max] + 1, Max); 59 } 60 return 0; 61 }
本文为博主原创文章,未经博主允许不得转载。