hdu-4185.loiol_skimming(简单二分匹配模型)

Posted bianjunting

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu-4185.loiol_skimming(简单二分匹配模型)相关的知识,希望对你有一定的参考价值。

 

 

 1 /*************************************************************************
 2     > File Name: hdu-4185.oil_skimming.cpp
 3     > Author: CruelKing
 4     > Mail: 2016586625@qq.com 
 5     > Created Time: 2019年09月03日 星期二 09时12分12秒
 6     本题思路:简单分析过后就可以知道如果一点a被另一个点b匹配,那么和b匹配的点c不可能和点a匹配,因为每个结点都只能匹配四个方向,所以这个匹配的图就可以看做是一个二分图,因此对于每个结点,将能和他匹配的边存入,接着跑一波二分匹配之后我们得到的是无向图情况下的最大匹配,所以除以二就是最后的答案.
 7  ************************************************************************/
 8 
 9 #include <cstdio>
10 #include <cstring>
11 #include <cmath>
12 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;
  

 

以上是关于hdu-4185.loiol_skimming(简单二分匹配模型)的主要内容,如果未能解决你的问题,请参考以下文章

英美概况的简答题

Flask入门小项目 - 搭建极简博客

龟兔赛跑故事的简笔画图片

最简分式

SpringBoot入门极简教程开篇

小白入门SpringBoot极简教程开篇