POJ - 1358 Housing Complexes(二分图最大匹配)
題目鏈接:點(diǎn)擊查看
題目大意:給出k塊m*n大小的土地,每塊土地由數(shù)字‘0’或26個(gè)大寫(xiě)字母組成,大寫(xiě)字母代表住戶(hù),數(shù)字‘0’代表空地,現(xiàn)在開(kāi)發(fā)商想盡可能多的修建大樓,每個(gè)大樓需要占用h*w的面積,而且每塊土地最多只能修一棟大樓,不過(guò)住戶(hù)不太愿意搬遷,經(jīng)過(guò)協(xié)商后,住戶(hù)答應(yīng)在每塊土地上,可以出售掉同一個(gè)住戶(hù)的所有房屋,不過(guò)在其他土地上就不允許再購(gòu)買(mǎi)該住戶(hù)的房屋了,問(wèn)在此條件下,開(kāi)發(fā)商最多可以建造多少棟大樓
題目分析:題目有點(diǎn)復(fù)雜,但理解之后就變得相當(dāng)簡(jiǎn)單了,因?yàn)槊繅K土地開(kāi)發(fā)商都可以選擇買(mǎi)掉任一住戶(hù)的所有房屋,以此來(lái)增加空地的可用面積,所以每一塊土地可以看做一個(gè)頂點(diǎn),每一個(gè)字母(住戶(hù)),也可以看做一個(gè)頂點(diǎn),因?yàn)槊恳粋€(gè)住戶(hù)只在一塊土地上出售房屋,所以就形成了一個(gè)一一對(duì)應(yīng)的關(guān)系,簡(jiǎn)單來(lái)說(shuō),就是一個(gè)二分圖匹配問(wèn)題,即以每塊土地來(lái)選擇特定的字母,進(jìn)而達(dá)到最大值的一個(gè)過(guò)程
這樣一來(lái)只要建好圖,然后跑一遍匈牙利算法就好了,我感覺(jué)難就難在該如何建圖上,一開(kāi)始實(shí)在沒(méi)有思路,參考了一下zx學(xué)長(zhǎng)的代碼之后,就豁然開(kāi)朗了,我們可以用二維前綴和來(lái)判斷,因?yàn)轭}目規(guī)定了每個(gè)大樓需要占掉h*w面積的土地,并且暗示出這個(gè)h*w的面積必須是h*w,而不能是w*h,這樣一來(lái)我們只需要在空地或當(dāng)前字母上,取值為1,否則取值為0,求一下二維前綴和,然后判斷哪一塊h*w大小的區(qū)間內(nèi)的值是h*w即可
這樣建完圖后,還有一個(gè)小細(xì)節(jié)需要注意一下,若某塊土地中,空地的大小已經(jīng)滿(mǎn)足建大樓的需求,也就是說(shuō)在當(dāng)前土地并不需要購(gòu)買(mǎi)用戶(hù)的房屋時(shí),直接讓答案+1即可,剩下的跑一遍匈牙利就好了
現(xiàn)在看zx學(xué)長(zhǎng)的代碼看多了,代碼風(fēng)格和學(xué)長(zhǎng)的風(fēng)格越來(lái)越像了,但水平好像還是不如zx學(xué)長(zhǎng)的十分之一QAQ
代碼:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=55;int k,n,m,h,w;char s[N][N];bool maze[N][N];//maze[k][character]int match[N];int sum[N][N];bool vis[N];bool cal(char ch) {for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(s[i][j]=='0'||s[i][j]==ch)sum[i][j]=1;elsesum[i][j]=0;sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];if(i>=h&&j>=w&&sum[i][j]-sum[i-h][j]-sum[i][j-w]+sum[i-h][j-w]==h*w)return true;}}return false; }bool dfs(int x) {for(int i=1;i<=26;i++){if(maze[x][i]&&!vis[i]){vis[i]=true;if(!match[i]||dfs(match[i])){match[i]=x;return true;}}} return false; }int main() { // freopen("input.txt","r",stdin);int t;cin>>t;while(t--){memset(match,0,sizeof(match));scanf("%d%d%d%d%d",&k,&n,&m,&h,&w);for(int i=1;i<=k;i++){for(int j=1;j<=n;j++)scanf("%s",s[j]+1);for(int j=0;j<=26;j++){char ch=j+'A'-1;maze[i][j]=cal(ch);}}int ans=0;for(int i=1;i<=k;i++){memset(vis,false,sizeof(vis));if(maze[i][0]||dfs(i))ans++;}printf("%d\n",ans);}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的POJ - 1358 Housing Complexes(二分图最大匹配)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: POJ - 2513 Colored S
- 下一篇: PAT (Advanced Level)