Hdu 1281 棋盘游戏 (二分匹配)

题目链接:

  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 }

 

posted @ 2015-08-01 09:33  罗茜  阅读(237)  评论(0编辑  收藏  举报