1. 程式人生 > 其它 >hdu------1281 棋盤遊戲(最小覆蓋點)

hdu------1281 棋盤遊戲(最小覆蓋點)

棋盤遊戲

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

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

杭電ACM集訓隊訓練賽(VI)

Recommend

詳細的程式碼: 最小覆蓋點=最大匹配

程式碼:

 1 /*Problem : 1281 ( 棋盤遊戲 )     Judge Status : Accepted
 2 RunId : 11517709    Language : C++    Author : huifeidmeng
 3 Code Render Status : Rendered By HDOJ C++ Code Render Version 0.01 Beta*/
 4 
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<cstdlib>
 8 using namespace std;
 9 const int maxn=105;
10 static int cont=1;
11 bool mat[maxn][maxn],vis[maxn];
12 int chess[maxn];
13  int n,m,k;
14 int match(int x){
15   for(int i=1;i<=m;i++){
16     if(mat[x][i]&&!vis[i]){
17       vis[i]=1;
18      if(!chess[i]||match(chess[i])){
19          chess[i]=x;
20          return 1;
21        }
22      }
23     }
24   return 0;
25 }
26 int a[maxn*maxn],b[maxn*maxn];
27 int main(){
28    //freopen("test.in","r",stdin);
29   while(scanf("%d%d%d",&n,&m,&k)!=EOF){
30     memset(mat,0,sizeof(mat));
31     memset(chess,0,sizeof(chess));
32     for(int i=0;i<k;i++){
33         scanf("%d%d",&a[i],&b[i]);
34         mat[a[i]][b[i]]=1;
35     }
36     int ans=0;
37     for(int i=1;i<=n;i++){
38       memset(vis,0,sizeof(vis));
39        ans+=match(i);
40     }
41     int res=0;  //重要點個數
42   //判斷一個點重不重要,去掉這個點看看對這個匹配有沒有影響就行了
43     for(int i=0;i<k;i++){
44       memset(chess,0,sizeof(chess));
45       mat[a[i]][b[i]]=0;  //拿掉那個點,再來一次匹配
46       int val=0;
47      for(int j=1;j<=n;j++){
48        memset(vis,0,sizeof(vis));
49         val+=match(j);
50         }
51        if(ans>val) res++;  //說明有影響...是一個重要點
52        mat[a[i]][b[i]]=1;  //將拿掉的那個點復原
53     }
54     printf("Board %d have %d important blanks for %d chessmen.n",cont++,res,ans);
55   }
56 return 0;
57 }