[ 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\n",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 */