【BZOJ 3175】 3175: [Tjoi2013]攻击装置(二分图匹配)
3175: [Tjoi2013]攻击装置
Description
给定一个01矩阵,其中你可以在0的位置放置攻击装置。每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2),(x-2,y-1),(x+1,y-2),(x+2,y-1),(x-1,y+2),(x-2,y+1), (x+1,y+2),(x+2,y+1)
求在装置互不攻击的情况下,最多可以放置多少个装置。Input
第一行一个整数N,表示矩阵大小为N*N。接下来N行每一行一个长度N的01串,表示矩阵。Output
一个整数,表示在装置互不攻击的情况下最多可以放置多少个装置。Sample Input
3
010
000
100
Sample Output
4HINT
100%数据 N<=200
Source
【分析】
以坐标和的奇偶分成2类,就是一个二分图,然后能攻击的连边跑匈牙利。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define Maxn 210 8 9 struct node 10 { 11 int x,y,next; 12 }t[Maxn*Maxn*10]; 13 int len,first[Maxn*Maxn]; 14 15 void ins(int x,int y) 16 { 17 t[++len].x=x;t[len].y=y; 18 t[len].next=first[x];first[x]=len; 19 } 20 21 int num[Maxn][Maxn]; 22 char s[Maxn]; 23 24 int bx[10]={0,-1,-2,1,2,-1,-2,1,2}, 25 by[10]={0,-2,-1,-2,-1,2,1,2,1}; 26 //(x-1,y-2),(x-2,y-1),(x+1,y-2),(x+2,y-1),(x-1,y+2),(x-2,y+1), (x+1,y+2),(x+2,y+1) 27 28 int xx[Maxn*Maxn],chw[Maxn*Maxn],match[Maxn*Maxn]; 29 30 bool ffind(int x,int nt) 31 { 32 for(int i=first[x];i;i=t[i].next) if(chw[t[i].y]!=nt) 33 { 34 int y=t[i].y; 35 chw[y]=nt; 36 if(match[y]==0||ffind(match[y],nt)) 37 { 38 match[y]=x; 39 return 1; 40 } 41 } 42 return 0; 43 } 44 45 46 int get_ans() 47 { 48 memset(match,0,sizeof(match)); 49 memset(chw,0,sizeof(chw)); 50 int nt=0,ans=0; 51 for(int i=1;i<=xx[0];i++) 52 { 53 nt++; 54 if(ffind(xx[i],nt)) ans++; 55 } 56 return ans; 57 } 58 59 int main() 60 { 61 int n; 62 scanf("%d",&n); 63 int h=0; 64 memset(num,0,sizeof(num)); 65 for(int i=1;i<=n;i++) 66 { 67 scanf("%s",s); 68 for(int j=0;j<n;j++) 69 { 70 if(s[j]=='0') num[i][j+1]=++h; 71 } 72 } 73 len=0; 74 memset(first,0,sizeof(first)); 75 xx[0]=0; 76 for(int i=1;i<=n;i++) 77 for(int j=1;j<=n;j++) if(num[i][j]!=0&&(i+j)%2==0) 78 { 79 for(int k=1;k<=8;k++) 80 { 81 int nx=i+bx[k],ny=j+by[k]; 82 if(nx<1||nx>n||ny<1||ny>n) continue; 83 if(num[nx][ny]==0) continue; 84 ins(num[i][j],num[nx][ny]); 85 } 86 xx[++xx[0]]=num[i][j]; 87 } 88 int ans=get_ans(); 89 printf("%d\n",h-ans); 90 return 0; 91 }
2017-02-22 13:22:40