HD1281棋盘游戏(匹配+好题)
棋盘游戏
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3372 Accepted Submission(s):
1997
Problem Description
小希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,这当然很简单,但是Gardon限制了只有某些格子才可以放,小希还是很轻松的解决了这个问题(见下图)注意不能放车的地方不影响车的互相攻击。
所以现在Gardon想让小希来解决一个更难的问题,在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下。但是某些格子若不放子,就无法保证放尽量多的“车”,这样的格子被称做重要点。Gardon想让小希算出有多少个这样的重要点,你能解决这个问题么?
![](http://acm.hdu.edu.cn/data/images/C21-1008-1.gif)
所以现在Gardon想让小希来解决一个更难的问题,在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下。但是某些格子若不放子,就无法保证放尽量多的“车”,这样的格子被称做重要点。Gardon想让小希算出有多少个这样的重要点,你能解决这个问题么?
![](http://acm.hdu.edu.cn/data/images/C21-1008-1.gif)
Input
输入包含多组数据,
第一行有三个数N、M、K(1<N,M<=100 1<K<=N*M),表示了棋盘的高、宽,以及可以放“车”的格子数目。接下来的K行描述了所有格子的信息:每行两个数X和Y,表示了这个格子在棋盘中的位置。
第一行有三个数N、M、K(1<N,M<=100 1<K<=N*M),表示了棋盘的高、宽,以及可以放“车”的格子数目。接下来的K行描述了所有格子的信息:每行两个数X和Y,表示了这个格子在棋盘中的位置。
Output
对输入的每组数据,按照如下格式输出:
Board T have C important blanks for L chessmen.
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
题意:如果某点不放棋子就不能达到最大的车;问这个点数的最大值
把车当成连接x,y的一条边,求最多能放车的数量就是求最大匹配,即x,y的匹配
求不重要的点就暴力枚举每一个点,假设没有这个点看看匹配数是否变小,这个做法很好
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int MAX = 110; 7 int g[MAX][MAX],vis[MAX],link[MAX]; 8 int n,m,k; 9 int findx(int x) 10 { 11 for(int i = 1; i <= m; i++) //注意这是m 12 { 13 if(g[x][i] == 1 && vis[i] == 0) 14 { 15 vis[i] = 1; 16 if(link[i] == 0 || findx(link[i])) 17 { 18 link[i] = x; 19 return true; 20 } 21 } 22 } 23 return false; 24 } 25 int getsum() 26 { 27 int sum = 0; 28 memset(link,0,sizeof(link)); 29 for(int i = 1; i <= n; i++) 30 { 31 memset(vis,0,sizeof(vis)); 32 if(findx(i)) 33 sum++; 34 } 35 return sum; 36 } 37 int main() 38 { 39 int t = 0; 40 while(scanf("%d%d%d", &n,&m,&k) != EOF) 41 { 42 int x,y,sum = 0,important = 0; 43 memset(g,0,sizeof(g)); //初始化 44 for(int i = 0; i < k; i++) 45 { 46 scanf("%d%d",&x,&y); 47 g[x][y] = 1; 48 } 49 sum = getsum(); 50 51 for(int i = 1; i <= n; i++) 52 { 53 for(int j = 1; j <= m; j++) 54 { 55 if(g[i][j]) 56 { 57 g[i][j] = 0; 58 if(sum > getsum()) 59 important++; 60 g[i][j] = 1; 61 } 62 } 63 } 64 printf("Board %d have %d important blanks for %d chessmen.\n",++t,important,sum); 65 } 66 return 0; 67 }