[BZOJ 1458] soldiers and bzoj1458 soldiers
1458: occupied by soldiers
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 632 Solved: 366
[Submit] [Status] [Discuss]
Description
There is an M * N chessboard, and some grids are obstacles. Now you need to select some grids to place some soldiers. One grid can hold up to one soldier, and the barrier cannot hold soldiers. We said these soldiers occupied the entire board when at least Li soldiers were placed in line I, and at least Cj soldiers were placed in column j. Now your task is to use a minimum number of soldiers to occupy the entire board.
Input
The numbers M, N, and K in the first row represent the number of rows, columns, and obstacles of the Board. The number of M in the second row indicates Li. The number of N in the third row indicates Ci. Next, there are K rows. There are two numbers in each row X, and Y represents (X, Y) This lattice is an obstacle.
Output
Output a number to indicate the minimum number of soldiers to be used. If no number of soldiers can occupy the entire board, output "JIONG !" (Without quotation marks)
Sample Input
4 4 4
1 1 1 1
0 1 0 3
1 4
2 2
3 3
4 3
Sample Output
4
Data range
M, N <= 100, 0 <= K <= M * N
The source sink has the smallest stream in the upper and lower bounds.
For details, see Network Flow Problems with upper and lower limits.
#include <iostream>#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <cstdlib>#define M 500005#include <queue>#define inf 0x3f3f3f3fusing namespace std;struct edge{ int from,to,cap,flow,ne;}E[M];int tot,h[M],d[M],s,t,cur[M],cant[105][105],v[M],n,m;void Addedge(int from,int to,int cap){ E[++tot]=(edge){from,to,cap,0,h[from]}; h[from]=tot; E[++tot]=(edge){to,from,0,0,h[to]}; h[to]=tot;}int bfs(){ for (int i=s;i<=t;i++) v[i]=0; v[s]=1; queue<int> q; q.push(s); d[s]=0; while (!q.empty()) { int x=q.front(); q.pop(); for (int i=h[x];i;i=E[i].ne) { edge e=E[i]; if (!v[e.to]&&e.cap>e.flow) { v[e.to]=1; d[e.to]=d[x]+1; q.push(e.to); } } } return v[t];}int dfs(int x,int a){ if (x==t||!a) return a; int flow=0; for (int &i=cur[x];i;i=E[i].ne) { edge &e=E[i]; if (d[e.to]!=d[x]+1) continue; int f=dfs(e.to,min(a,e.cap-e.flow)); if (f>0) { flow+=f; a-=f; e.flow+=f; E[i^1].flow-=f; if (!a) break; } } return flow;}int dinic(){ int flow=0; while (bfs()) { for (int i=s;i<=t;i++) cur[i]=h[i]; flow+=dfs(s,inf); } return flow;}int main(){ tot=1; int k; scanf("%d%d%d",&n,&m,&k); int jud=0; int s1=n+m+1,t1=n+m+2; s=0,t=n+m+3; for (int i=1;i<=n;i++) { int x; scanf("%d",&x); jud+=x; Addedge(s1,i,m-x); Addedge(s,i,x),Addedge(s1,t,x); } for (int i=1;i<=m;i++) { int x; scanf("%d",&x); Addedge(i+n,t1,n-x); Addedge(s,t1,x),Addedge(i+n,t,x); } for (int i=1;i<=k;i++) { int x,y; scanf("%d%d",&x,&y); cant[x][y]=1; } for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (!cant[i][j]) Addedge(i,n+j,1); int flow=dinic(); if (flow==jud) { Addedge(t1,s1,inf); flow-=dinic(); printf("%d\n",E[tot-1].flow); } else puts("JIONG!"); return 0;}