Description
有一個M * N的棋盤,有的格子是障礙。現在你要選擇一些格子來放置一些士兵,一個格子里最多可以放置一個士兵,障礙格里不能放置士兵。我們稱這些士兵占領了整個棋盤當滿足第i行至少放置了Li個士兵, 第j列至少放置了Cj個士兵。現在你的任務是要求使用最少個數的士兵來占領整個棋盤。
第一行兩個數M, N, K分別表示棋盤的行數,列數以及障礙的個數。 第二行有M個數表示Li。 第三行有N個數表示Ci。 接下來有K行,每行兩個數X, Y表示(X, Y)這個格子是障礙。
Output
輸出一個數表示最少需要使用的士兵個數。如果無論放置多少個士兵都沒有辦法占領整個棋盤,輸出”JIONG!” (不含引號)
4 4 4
1 1 1 1
0 1 0 3
1 4
2 2
3 3
4 3
Sample Output
4
數據范圍
M, N <= 100, 0 <= K <= M * N
分析
GDKOI前復習一波網絡流模板 要把問題轉換成先把所有格子都填滿,然后再求最多能刪掉多少個士兵。 用numl[i]表示第i行可以放多少個士兵,numc[i]表示第i列能放多少個士兵。 那么s向每行連流量為numl[i]-L[i]的邊,每列向t連流量為numc[i]-c[i]的邊,若第i行第j列不是障礙物則在第i行第j列連流量為1的邊,跑一邊最大流,然后ans=n*m-k-maxflow
代碼
#include <bits/stdc++.h>#define N 305#define INF 0x7fffffusing namespace std;struct NOTE{ int to,next,c,op;}e[N*1000];int cnt,next[N];int c[N],l[N];int numl[N],numc[N];int dis[N],cur[N];int Map[N][N];int n,m,k;int s,t;int ans;void add(int x,int y,int c){ e[++cnt].to = y; e[cnt].next = next[x]; e[cnt].c = c; e[cnt].op = cnt+1; next[x] = cnt; e[++cnt].to = x; e[cnt].next = next[y]; e[cnt].c = 0; e[cnt].op = cnt-1; next[y] = cnt;}bool bfs(){ queue<int> Q; for (int i = s; i <= t; i++) { dis[i] = 0; } dis[s] = 1; Q.push(s); while (!Q.empty()) { int v = Q.front(); Q.pop(); for (int i = next[v]; i; i = e[i].next) { if (e[i].c && !dis[e[i].to]) { int now = e[i].to; dis[now] = dis[v] + 1; Q.push(now); if (e[i].to == t) return 1; } } } return 0;}int dfs(int x,int maxf){ if (x == t || maxf == 0) return maxf; int ret = 0; for (int &i = cur[x]; i; i = e[i].next) { if(e[i].c && dis[e[i].to] == dis[x] + 1) { int f = dfs(e[i].to,min(maxf - ret,e[i].c)); ret += f; e[i].c -= f; e[e[i].op].c += f; if (ret == maxf) break; } } return ret;}void dinic(){ while (bfs()) { for (int i = s; i <= t; i++) cur[i] = next[i]; ans += dfs(s,INF); }}int main(){ scanf("%d%d%d",&n,&m,&k); for (int i = 1; i <= n; i++) { scanf("%d",&l[i]); numl[i]=m; } for (int i = 1; i <= m; i++) { scanf("%d",&c[i]); numc[i] = n; } for(int i = 1; i <= k; i++) { int x,y; scanf("%d%d",&x,&y); Map[x][y] = 1; numl[x]--; numc[y]--; } s = 0; t = n + m + 1; for (int i = 1; i <= n; i++) { if (numl[i] < l[i]) {