POJ 2446 Chessboard【二分图匹配】
题意: 给你一个 n*m 的方格,但是里面有些地方是有洞的,问你能否用1 X 2 的板砖铺满空白的地方,
例如:

分析: 二分图匹配,关键在于建图,以奇数格(i+j)%2==1 为一个集合,以偶数格为另一个集合,因为任意一个铺设都是有一个奇数格和一个偶数格构成的,
最后如果匹配的个数是空白格数的一半,即完全匹配,说明能够铺满。
 View Code
View Code 
#include<stdio.h> #include<string.h> #define clr(x)memset(x,0,sizeof(x)) struct node { int to,next; }q[1000000]; int head[1200]; int link[1200]; int v[1200]; int tot; void add(int s,int u) { q[tot].to=u; q[tot].next=head[s]; head[s]=tot++; } int find(int x) { int i,k; for(i=head[x];i;i=q[i].next) { k=q[i].to; if(!v[k]) { v[k]=1; if(link[k]==0||find(link[k])) { link[k]=x; return 1; } } } return 0; } int map[35][35]; int s[1205]; int main() { int sn,i,n,j,m,k,a,b,sum,flag; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { if((n*m-k)&1) { printf("NO\n"); continue; } clr(head); clr(link); tot=1; for(i=1;i<=k;i++) { scanf("%d%d",&a,&b); map[b][a]=1; } sn=0; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { flag=0; if(((i+j)&1)&&map[i][j]==0) { if(i>1&&map[i-1][j]==0) { add(i*m+j,(i-1)*m+j); flag=1; } if(j>1&&map[i][j-1]==0) { add(i*m+j,i*m+j-1); flag=1; } if(i<n&&map[i+1][j]==0) { add(i*m+j,(i+1)*m+j); flag=1; } if(j<m&&map[i][j+1]==0) { add(i*m+j,i*m+j+1); flag=1; } if(flag) s[sn++]=i*m+j; } } } sum=0; for(i=0;i<sn;i++) { clr(v); if(find(s[i])) sum++; } if(sum==(n*m-k)/2) printf("YES\n"); else printf("NO\n"); } return 0; }
 
                     
                    
                 
                    
                


 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号