hdu-4185.loiol_skimming (simple binary matching model)

 

 

1  / * *********************************************** *************************
 2      > the Name File: HDU-4185.oil_skimming.cpp
 . 3      > the Author: CruelKing
 . 4      > Mail: 2016586625 @ QQ. COM 
 5      > the Created time: 2019 Nian 09 Yue 03 Tuesday, 09 hours 12 minutes 12 seconds
 6      this question ideas: after a simple analysis can tell if it is a match to another point b, then b and c can not match point and point a matching, because each node can only match the four directions, so this can be seen in FIG matching a bipartite graph, so for each node will be able to match his side and stored, followed by a run after the match we get half wave is not the largest case of matching the figure below, so divided by two is the final answer.
 7  *********************** **************************** * / 
. 8  
. 9 #include <cstdio>
 10 #include <CString>
 . 11 #include <the cmath>
 12 is  the using namespace std;
13 
14 const int maxn = 600 + 5;
15 char str[maxn][maxn];
16 
17 int n;
18 int linker[maxn * maxn];
19 bool used[maxn * maxn];
20 int tot, head[maxn * maxn];
21 int un[maxn * maxn], cnt;
22 
23 struct Edge {
24     int to, next;
25 } edge[maxn * maxn * 4 + 5];
26 
27 void init() {
28     memset(head, -1, sizeof head);
29     tot = 0;
30 }
31 
32 void addedge(int u, int v) {
33     edge[tot] = (Edge) {v, head[u]};
34     head[u] = tot ++;
35 }
36 
37 bool dfs(int u) {
38     for(int k = head[u]; ~k; k = edge[k].next) {
39         int v = edge[k].to;
40         if(!used[v]) {
41             used[v] = true;
42             if(linker[v] == -1 || dfs(linker[v])) {
43                 linker[v] = u;
44                 return true;
45             }
46         }
47     }
48     return false;
49 }
50 
51 int main() {
52     int k, Case = 0;
53     scanf("%d", &k);
54     while(k --) {
55         init();
56         cnt = 0;
57         scanf("%d", &n);
58         for(int i = 0; i < n; i ++) {
59             scanf("%s", str[i]);
60         }
61         for(int i = 0; i < n; i ++) {
62             for(int j = 0; j < n; j ++) {
63                 if(str[i][j] == '#') {
64                     un[cnt ++] = (i * n + j + 1);
65                     for(int dx = -1; dx <= 1; dx ++) {                    
66                         for(int dy = -1; dy <= 1; dy ++) {                        
67                             if(abs(dx - dy) == 1) {        
68                                 if(dx + i >= 0 && dx + i < n && dy + j >= 0 && dy + j < n) {                    
69                                     if(str[dx + i][dy + j] == '#') addedge(i * n + j + 1, (i + dx) * n + j + dy + 1);
70                                 }
71                             }
72                         }
73                     }
74                 }
75             }
76         }
77         int res = 0;
78         memset(linker, -1, sizeof linker);
79         for(int i = 0; i < cnt; i ++) {
80             memset(used, false, sizeof used);
81             if(dfs(un[i])) res ++;
82         }
83         printf("Case %d: %d\n", ++Case, res / 2);
84     }
85     return 0;
  }

 

Guess you like

Origin www.cnblogs.com/bianjunting/p/11453537.html