hdu 4185 二分图匹配

题意用1*2的木板覆盖矩阵中的‘#’,(木板要覆盖的只能是‘#’),问最多能用几个木板覆盖

将#抽象为二分图的点,一个木板就是一个匹配,注意最后结果要除以2

Sample Input

1
6
......
.##...
.##...
....#.
....##
......

Sample Output
Case 1: 3
 
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 1000000007
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 typedef long long ll;
13 #define cl(a) memset(a,0,sizeof(a))
14 #define ts printf("*****
");
15 const int MAXN=1005;
16 int n,m,tt;
17 char s[MAXN][MAXN];
18 int uN,vN;//u,v的数目,使用前面必须赋值
19 int g[MAXN][MAXN];//邻接矩阵
20 int linker[MAXN];
21 bool used[MAXN];
22 int num[MAXN][MAXN];
23 bool dfs(int u)
24 {
25     for(int v=0;v<vN;v++)
26     if(g[u][v]&&!used[v])
27     {
28         used[v]=true;
29         if(linker[v]==-1||dfs(linker[v]))
30         {
31             linker[v] = u;
32             return true;
33         }
34     }
35     return false;
36 }
37 int hungary()
38 {
39     int res=0;
40     memset(linker,-1,sizeof(linker));
41     for(int u=0;u<uN;u++)
42     {
43         memset(used,false,sizeof(used));
44         if(dfs(u))res++;
45     }
46     return res;
47 }
48 int main()
49 {
50     int i,j,k;
51     #ifndef ONLINE_JUDGE
52     freopen("1.in","r",stdin);
53     #endif
54     int ca=0;
55     scanf("%d",&tt);
56     while(tt--)
57     {
58         scanf("%d",&n);
59         cl(g);
60         int tot=0;
61         cl(num);
62         for(i=0;i<n;i++)
63         {
64             scanf("%s",&s[i]);
65             for(j=0;j<n;j++)
66             {
67                 if(s[i][j]=='#')    num[i][j]=tot++;
68             }
69         }
70 
71         uN=vN=tot;
72         for(i=0;i<n;i++)
73         {
74             for(j=0;j<n;j++)
75             {
76                 if(s[i][j]=='#')
77                 {
78                     if(s[i+1][j]=='#'&&i+1<n)  g[num[i][j]][num[i+1][j]]=1;
79                     if(s[i][j+1]=='#'&&j+1<n)  g[num[i][j]][num[i][j+1]]=1;
80                     if(s[i-1][j]=='#'&&i-1>=0)  g[num[i][j]][num[i-1][j]]=1;
81                     if(s[i][j-1]=='#'&&j-1>=0)  g[num[i][j]][num[i][j-1]]=1;
82                 }
83             }
84         }
85         ca++;
86         printf("Case %d: %d
",ca,hungary()/2);
87     }
88 }
原文地址:https://www.cnblogs.com/cnblogs321114287/p/4312687.html