1. 程式人生 > >POJ 2226 Muddy Fields 二分圖(難點在於建圖)

POJ 2226 Muddy Fields 二分圖(難點在於建圖)

這一 hid mil one int blog span fields string

題意:給定一個矩陣和它的N行M列,其中有一些地方有水,現在有一些長度任意,寬為1的木板,要求在板不跨越草,用一些木板蓋住這些有水的地方,問至少需要幾塊板子?

思路:首先想到如果沒有不準跨越草的條件則跟POJ 3041題意一樣(如果想看的話可以點擊這裏),然而這一題多了個條件,那麽將矩陣轉化的方式需要改變,不能直接將行列分成兩個集合了。需要先查看兩遍矩陣,一遍橫向查看有無連續‘*’的情況,若連續說明一塊板子就可以覆蓋,所以標記為同樣的數字,反之則不同;同理另一遍縱向查看矩陣連續‘*‘的情況,處理方式同上。這樣就建圖完畢了。

技術分享圖片
  1 #include<cstdio>
  2 
  3
#include<cstring> 4 5 #include<iostream> 6 7 #include<algorithm> 8 9 using namespace std; 10 11 12 13 const int N = 600; 14 15 int n, m, p, q; 16 17 bool lin[N][N]; 18 19 int used[N], arr[N], mark[N][N]; 20 21 char map[N][N]; 22 23 24 25 bool
find(int x) 26 27 { 28 29 for(int j = 1; j <= q; j++) 30 31 { 32 33 if(lin[x][j] && used[j] == 0) 34 35 { 36 37 used[j] = 1; 38 39 if(arr[j] == 0 || find(arr[j])) 40 41 { 42 43 arr[j] = x;
44 45 return true; 46 47 } 48 49 } 50 51 } 52 53 return false; 54 55 } 56 57 58 59 int main() 60 61 { 62 63 int r, c; 64 65 while(~scanf("%d%d", &n, &m)) 66 67 { 68 69 memset(map, 0, sizeof(map)); 70 71 for(int i = 0; i < n; i++) 72 73 { 74 75 scanf("%s", &map[i]); 76 77 } 78 79 memset(lin, false , sizeof(lin)); 80 81 memset(arr, 0, sizeof(arr)); 82 83 p = 0; 84 85 for(int i = 0; i < n; i++) 86 87 { 88 89 for(int j = 0; j < m; j++) 90 91 { 92 93 if(map[i][j] == *) 94 95 { 96 97 if(map[i][j-1] != *)//橫向查看 98 99 { 100 101 p++; 102 103 } 104 105 mark[i][j] = p; 106 107 } 108 109 } 110 111 } 112 113 q = 0; 114 115 for(int j = 0; j < m; j++) 116 117 { 118 119 for(int i = 0; i < n; i++) 120 121 { 122 123 if(map[i][j] == *) 124 125 { 126 127 if(map[i-1][j] != *)//縱向查看 128 129 { 130 131 q++; 132 133 } 134 135 lin[mark[i][j]][q] = true;//橫向已經檢查完了可以直接建圖了 136 137 } 138 139 } 140 141 } 142 143 int all = 0; 144 145 for(int i = 1; i <= p; i++) 146 147 { 148 149 memset(used, 0, sizeof(used)); 150 151 if(find(i)) 152 153 ++all; 154 155 } 156 157 printf("%d\n", all); 158 159 } 160 161 return 0; 162 163 }
View Code

POJ 2226 Muddy Fields 二分圖(難點在於建圖)