码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-09-03 16:36:44      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:思路   pac   scanf   time   linker   har   模型   div   不可   

 

 

 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(简单二分匹配模型)

标签:思路   pac   scanf   time   linker   har   模型   div   不可   

原文地址:https://www.cnblogs.com/bianjunting/p/11453537.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!