[poj2446]Chessboard
生活随笔
收集整理的這篇文章主要介紹了
[poj2446]Chessboard
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Description
給定一個(gè)m×n的棋盤,上面有k個(gè)洞,求是否能在不重復(fù)覆蓋且不覆蓋到洞的情況下,用2×1的卡片完全覆蓋棋盤。
Input
第一行有三個(gè)整數(shù)n,m,k(0<m,n<=32, 0<=k<m×n),m表示行數(shù),n表示列數(shù)。
接下來k行,每行兩個(gè)整數(shù)y,x,表示(x,y)上有個(gè)洞。
Output
如果能覆蓋,輸出YES;否則輸出NO。
Sample Input
4 3 2
2 1
3 3
Sample Output
YES
Solution
32×32的范圍如果暴搜剪枝能力比較強(qiáng)的人也許能過吧,但是我并沒有那個(gè)能力。
2×1的卡片去覆蓋的話,就是兩個(gè)相鄰的格子為一對,且每個(gè)格子只能屬于一對(有洞的格子不屬于任何一對)。
怎么有點(diǎn)像二分圖匹配?那就想想怎么構(gòu)圖吧。
定義兩格子相鄰當(dāng)且僅當(dāng)它們有一條公共邊時(shí)。
那么兩個(gè)相鄰的格子就得在不同集合里,按這樣分正好能分成兩個(gè)集合。
然后兩個(gè)可放卡片的相鄰格子連一條邊,這樣二分圖就構(gòu)成功了。
1 #include<set> 2 #include<cmath> 3 #include<ctime> 4 #include<queue> 5 #include<stack> 6 #include<cstdio> 7 #include<vector> 8 #include<cstring> 9 #include<cstdlib> 10 #include<iostream> 11 #include<algorithm> 12 #define D 5 13 #define N 35 14 #define K 513 15 #define M 2049 16 using namespace std; 17 struct graph{ 18 int nxt,to; 19 }e[M]; 20 int x[D]={0,0,0,1,-1},y[D]={0,1,-1,0,0}; 21 int g[K],fr[N*N],m,n,k,cnt,tot,sum; 22 bool b[N][N],u[N*N]; 23 inline void addedge(int x,int y){ 24 e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y; 25 } 26 inline bool match(int k){ 27 for(int i=g[k];i;i=e[i].nxt) 28 if(!u[e[i].to]){ 29 u[e[i].to]=true; 30 if(!fr[e[i].to]||match(fr[e[i].to])){ 31 fr[e[i].to]=k;return true; 32 } 33 } 34 return false; 35 } 36 inline bool hungary(){ 37 for(int i=1;i<=tot;i++){ 38 memset(u,0,sizeof(u)); 39 if(!match(i)) return false; 40 } 41 return true; 42 } 43 inline void init(){ 44 scanf("%d%d%d",&m,&n,&k); 45 for(int i=1;i<=m;i++) 46 for(int j=1;j<=n;j++) 47 b[i][j]=true; 48 for(int i=1,j,l;i<=k;i++){ 49 scanf("%d%d",&j,&l); 50 b[l][j]=false; 51 } 52 for(int i=1;i<=m;i++) 53 for(int j=!(i&1)+1;j<=n;j+=2) 54 if(b[i][j]){ 55 ++tot; 56 for(int l=1;l<D;l++) 57 if(b[i+x[l]][j+y[l]]) 58 addedge(tot,(i+x[l]-1)*n+j+y[l]); 59 } 60 for(int i=1;i<=m;i++) 61 for(int j=(i&1)+1;j<=n;j+=2) 62 if(b[i][j]) sum++; 63 if(sum==tot&&hungary()) printf("YES\n"); 64 else printf("NO\n"); 65 } 66 int main(){ 67 freopen("chessboard.in","r",stdin); 68 freopen("chessboard.out","w",stdout); 69 init(); 70 fclose(stdin); 71 fclose(stdout); 72 return 0; 73 }?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/AireenYe/p/5658005.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的[poj2446]Chessboard的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql dbutil_DBUtil连
- 下一篇: 【IDE插件】- XCode6代码注释之