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

 1 /*************************************************************************
 2     > File Name: hdu-4185.oil_skimming.cpp
 3     > Author: CruelKing
 4     > Mail: [email protected]
 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;  }

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

时间: 2024-09-30 10:41:42

hdu-4185.loiol_skimming(简单二分匹配模型)的相关文章

hdu 4185 Oil Skimming(二分匹配)

Oil Skimming Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 883    Accepted Submission(s): 374 Problem Description Thanks to a certain "green" resources company, there is a new profitable

HDU 2119 Matrix 简单二分匹配

行做x集,列做y集,1就给该行该列连一条边,输出最大匹配边即可 #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<set> using namespace std; #define N 105 int lef[N], pn;//lef[v]表示Y集的点v 当前连接的点 , pn为x点集的

HDU 1281 棋盘游戏(二分匹配 与 删边)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281 根据题目描述,什么是重要点?在求出最大匹配后,进行枚举,依次删边,看最大匹配数会不会发生改变,改变的话,那么该点就是重要点. #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <

HDU 1083 裸的二分匹配

Courses Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3424    Accepted Submission(s): 1650 Problem Description Consider a group of N students and P courses. Each student visits zero, one or

hdu 1054 Strategic Game (二分匹配)

Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4697    Accepted Submission(s): 2125 Problem Description Bob enjoys playing computer games, especially strategic games, but somet

hdu 1281 棋盘游戏 (二分匹配)

//是象棋里的车 符合二分匹配 # include<stdio.h> # include<algorithm> # include<string.h> using namespace std; int n,m,pp[110][110],map[110],vis[110]; int bfs(int x) { for(int i=1;i<=m;i++) { if(!vis[i]&&pp[x][i]) { vis[i]=1; if(!map[i]||bf

hdu 1281 棋盘游戏(二分匹配)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281 棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2905    Accepted Submission(s): 1702 Problem Description 小希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放尽

HDU 1150 Machine Schedule (二分匹配)

Machine Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Description As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduli

HDU 1045 Fire Net (二分匹配)

Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Description Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street