[ An Ac a Day ^_^ ] UVALive 2635 Housing Complexes 二分图最大匹配

快要比赛了 看看原来做过的题 感觉这道题当时做的还是挺费劲的 所以发一下

题意:

一个土豪要建别墅 因为有的地区地方不够大 所以要拆屋子

每个地方的字母就是对应开发商的地盘

没有字母的就是自由土地

一个开发商的土地只能拆一次

一片土地只能建一个别墅

问最多能建几个别墅

思路:

建图之后直接跑算法……

坑点是如果直接可以建别墅 就不用跑算法直接+1……

而且一片土地只能建一个别墅……

算法还是很模板的

(PS:代码太长风格不好的话真的没有可读性-_-||)

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<math.h>
  5 #include<string.h>
  6 #include<string>
  7 #include<map>
  8 #include<set>
  9 #include<vector>
 10 #include<queue>
 11 #define M(a,b) memset(a,b,sizeof(a))
 12 #define ll long long
 13 using namespace std;
 14 const int inf=0x3f3f3f;
 15 int linker[150];
 16 bool zimu[50];
 17 int match[150][150];
 18 bool visy[150],vis[150][150];
 19 bool jump[105];
 20 bool find_(int a)
 21 {
 22     for(int i=1; i<27; i++)
 23     {
 24         if(match[a][i]==1&&visy[i]==0)
 25         {
 26             visy[i]=1;
 27             if(linker[i]==0||find_(linker[i]))
 28             {
 29                 linker[i]=a;
 30                 return true;
 31             }
 32         }
 33     }
 34     return false;
 35 }
 36 int main()
 37 {
 38     int T;
 39     scanf("%d",&T);
 40     while(T--)
 41     {
 42         M(jump,0);
 43         M(linker,0);
 44         M(match,0);
 45         int s,m,n,h,w;
 46         scanf("%d%d%d%d%d",&s,&m,&n,&h,&w);
 47         getchar();
 48         for(int i=0; i<s; i++)
 49         {
 50             char map_[m+1][n+1];
 51             memset(zimu,false,sizeof(zimu));
 52             for(int j=0; j<m; j++)
 53                 gets(map_[j]);
 54             for(int j=0; j<m; j++)
 55                 for(int k=0; k<n; k++)
 56                     if(map_[j][k]!='0') zimu[map_[j][k]-'A']=true;
 57             for(int j=0; j<26; j++)
 58             {
 59                 int cnt=0;
 60                 if(zimu[j])
 61                 {
 62                     char map_1[m+1][n+1];
 63                     for(int k=0; k<m; k++)
 64                         for(int l=0; l<n; l++)
 65                             if(map_[k][l]=='A'+j) map_1[k][l]='0';
 66                             else map_1[k][l]=map_[k][l];
 67                     M(vis,0);
 68                     for(int k=0; k+h-1<m; k++)
 69                     {
 70                         for(int l=0; l+w-1<n; l++)
 71                         {
 72                             if(map_1[k][l]=='0'&&!vis[k][l]&&k+h-1<m&&l+w-1<n)
 73                             {
 74                                 bool ok=true;
 75                                 for(int p=0; p<h; p++)
 76                                 {
 77                                     for(int q=0; q<w; q++)
 78                                     {
 79                                         if(map_1[k+p][l+q]!='0'&&!vis[k+p][l+q])
 80                                         {
 81                                             ok=false;
 82                                         }
 83                                     }
 84                                 }
 85                                 if(ok) cnt=1;
 86                             }
 87                         }
 88                     }
 89                 }
 90                 match[i+1][j+1]=cnt;
 91                 if(j+1==26)
 92                 {
 93                     M(vis,0);
 94                     bool ok=true;
 95                     cnt=0;
 96                     for(int k=0; k+h-1<m; k++)
 97                     {
 98                         for(int l=0; l+w-1<n; l++)
 99                         {
100                             ok=true;
101                             if(map_[k][l]=='0'&&!vis[k][l])
102                             {
103                                 for(int p=0; p<h; p++)
104                                 {
105                                     for(int q=0; q<w; q++)
106                                     {
107                                         if(map_[k+p][l+q]!='0'&&!vis[k+p][l+q])
108                                         {
109                                             ok=false;
110                                         }
111                                     }
112                                 }
113                                 if(ok) cnt=1;
114                             }
115                         }
116                     }
117                     if(cnt) jump[i+1]=true;
118                 }
119             }
120         }
121         int ans=0;
122         for(int i=1; i<=s; i++)
123         {
124             M(visy,0);
125             if(jump[i]) ans++;
126             else if(find_(i)) ans++;
127         }
128         printf("%d
",ans);
129     }
130     return 0;
131 }
132 /*
133 
134 2
135 3 4 3 3 2
136 A0B
137 000
138 0A0
139 00B
140 AA0
141 00B
142 0B0
143 000
144 A0A
145 000
146 B00
147 B00
148 3 4 3 3 2
149 A0B
150 000
151 0A0
152 00B
153 AA0
154 00B
155 0B0
156 000
157 A0A
158 000
159 0B0
160 B00
161 
162 */
原文地址:https://www.cnblogs.com/general10/p/5858766.html