BZOJ3175:[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
010
000
100
Sample Output
4
HINT
100%数据 N<=200
Solution
数组咋又双叒叕开小了……不过竟然还有90 数据良心(划掉)
第一眼读完题:这咋和炮兵阵地这么像,状压没跑了!
为了验证点击题解:网络流
emmm……我好像傻了这不就是骑士共存么= =……
裸的二分图最大独立集啊QAQ
Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<queue> 6 #define M (1000000+10) 7 #define N (40000+10) 8 #define id(x,y) (x-1)*n+y 9 using namespace std; 10 struct node 11 { 12 int Flow; 13 int next; 14 int to; 15 } edge[M*2]; 16 int Depth[N]; 17 int head[N],num_edge,cnt; 18 int n,m,s,e,x,y,INF,a[205][205],color[205][205]; 19 int dx[10]= {0,-2,-1,+1,+2,-2,-1,+1,+2}; 20 int dy[10]= {0,-1,-2,-2,-1,+1,+2,+2,+1}; 21 char st[N]; 22 queue<int>q; 23 24 void add(int u,int v,int l) 25 { 26 edge[++num_edge].to=v; 27 edge[num_edge].Flow=l; 28 edge[num_edge].next=head[u]; 29 head[u]=num_edge; 30 } 31 32 bool Bfs(int s,int e) 33 { 34 memset(Depth,0,sizeof(Depth)); 35 q.push(s); 36 Depth[s]=1; 37 while (!q.empty()) 38 { 39 int x=q.front(); 40 q.pop(); 41 for (int i=head[x]; i!=0; i=edge[i].next) 42 if (!Depth[edge[i].to] && edge[i].Flow>0) 43 { 44 Depth[edge[i].to]=Depth[x]+1; 45 q.push(edge[i].to); 46 } 47 } 48 return Depth[e]; 49 } 50 51 int Dfs(int x,int low) 52 { 53 int Min,f=0; 54 if (x==e || low==0) 55 return low; 56 for (int i=head[x]; i!=0; i=edge[i].next) 57 if (edge[i].Flow>0 && Depth[edge[i].to]==Depth[x]+1 && (Min=Dfs(edge[i].to,min(low,edge[i].Flow)))) 58 { 59 edge[i].Flow-=Min; 60 edge[((i-1)^1)+1].Flow+=Min; 61 low-=Min; 62 f+=Min; 63 if (low==0) return f; 64 } 65 if (!f) Depth[x]=-1; 66 return f; 67 } 68 69 int Dinic(int s,int e) 70 { 71 int Ans=0; 72 while (Bfs(s,e)) 73 Ans+=Dfs(s,0x7fffffff); 74 return Ans; 75 } 76 77 int main() 78 { 79 scanf("%d",&n); 80 s=0,e=200*200+1; 81 for (int i=1; i<=n; ++i) 82 { 83 scanf("%s",st); 84 for (int j=1; j<=n; ++j) 85 { 86 a[i][j]=st[j-1]-'0'; 87 color[i][j]=(i+j)%2; 88 if (a[i][j]==1) continue; 89 cnt++; 90 if (color[i][j]==0) add(s,id(i,j),1), add(id(i,j),s,0); 91 else add(id(i,j),e,1), add(e,id(i,j),0); 92 } 93 } 94 for (int i=1; i<=n; ++i) 95 for (int j=1; j<=n; ++j) 96 { 97 if (a[i][j]==1 || color[i][j]==1) continue; 98 for (int k=1; k<=8; ++k) 99 { 100 int x=i+dx[k],y=j+dy[k]; 101 if (x<1 || x>n || y<1 || y>n || a[x][y]==1) continue; 102 add(id(i,j),id(x,y),1); 103 add(id(x,y),id(i,j),0); 104 } 105 } 106 printf("%d",cnt-Dinic(s,e)); 107 }