HDOJ1281 棋盘游戏[匈牙利(最大匹配)+枚举]

棋盘游戏

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1286    Accepted Submission(s): 737


Problem Description
小希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,这当然很简单,但是Gardon限制了只有某些格子才可以放,小希还是很轻松的解决了这个问题(见下图)注意不能放车的地方不影响车的互相攻击。
所以现在Gardon想让小希来解决一个更难的问题,在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下。但是某些格子若不放子,就无法保证放尽量多的“车”,这样的格子被称做重要点。Gardon想让小希算出有多少个这样的重要点,你能解决这个问题么?
 
Input
输入包含多组数据,
第一行有三个数N、M、K(1<N,M<=100 1<K<=N*M),表示了棋盘的高、宽,以及可以放“车”的格子数目。接下来的K行描述了所有格子的信息:每行两个数X和Y,表示了这个格子在棋盘中的位置。
 
Output
对输入的每组数据,按照如下格式输出:
Board T have C important blanks for L chessmen.
 
Sample Input
3 3 4 1 2 1 3 2 1 2 2 3 3 4 1 2 1 3 2 1 3 2
 
Sample Output
Board 1 have 0 important blanks for 2 chessmen. Board 2 have 3 important blanks for 3 chessmen.
 
Author
Gardon
 
Source
 
Recommend
lcy
 
 
 
 
 
 
关键是找最大匹配,然后枚举判断就好。
code:
 1 #include<iostream>
 2 using namespace std;
 3 
 4 #define MAXN 110
 5 
 6 int map[MAXN][MAXN];
 7 int path[MAXN];
 8 int vst[MAXN];
 9 int n,m,k;
10 
11 bool dfs(int v)
12 {
13     int i;
14     for(i=1;i<=m;i++)
15     {
16         if(!vst[i]&&map[v][i])
17         {
18             vst[i]=1;
19             if(path[i]==-1||dfs(path[i]))
20             {
21                 path[i]=v;
22                 return true;
23             }
24         }
25     }
26     return false;
27 }
28 
29 int hungary()
30 {
31     int i;
32     int cnt=0;
33     memset(path,-1,sizeof(path));
34     for(i=1;i<=n;i++)
35     {
36         memset(vst,0,sizeof(vst));
37         if(dfs(i))
38             cnt++;
39     }
40     return cnt;
41 }
42 
43 int main()
44 {
45     int i,j;
46     int a,b;
47     int cnt;
48     int ans;
49     int temp;
50     int t=1;
51     while(~scanf("%d%d%d",&n,&m,&k))
52     {
53         cnt=0;
54         memset(map,0,sizeof(map));
55         for(i=0;i<k;i++)
56         {
57             scanf("%d%d",&a,&b);
58             map[a][b]=1;
59         }
60         ans=hungary();
61         for(i=1;i<=n;i++)
62             for(j=1;j<=m;j++)
63             {
64                 if(map[i][j])
65                 {
66                     map[i][j]=0;
67                     temp=hungary();
68                     map[i][j]=1;
69                     if(temp!=ans)
70                         cnt++;
71                 }
72             }
73         printf("Board %d have %d important blanks for %d chessmen.\n",t++,cnt,ans);
74     }
75     return 0;
76 }
原文地址:https://www.cnblogs.com/XBWer/p/2653878.html