那天听
dyx
d
y
x
讲课还是懵逼了半天 结果发现自己根本没怎么做过网络流, 板子都不会打了
qwq
q
w
q
还是一点点从他的课件里刷起来把
这个题我们首先可以换种思维方法 在有限制的情况下放最少的士兵
可以把所有士兵放上去之后 在有限制的情况下删最多的士兵
这样子建立一个超级源
S
S
向每一行连一条流量为当前点数减去限制的边, 代表这一行最多能删几个点 每一列向超级汇也连一条这样的边, 那么对于每一个没有障碍的点
(x,y)
(
x
,
y
)
连一条行
x
x
到列的边 然后跑最大流即可
最后的答案
ans=n∗m−k−Maxflow
a
n
s
=
n
∗
m
−
k
−
M
a
x
f
l
o
w
Codes
#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)
#define go(x, i) for(register int i = head[x]; i; i = nxt[i])
#define inf (0x3f3f3f3f)
using namespace std;
const int maxn = 100 + 10;
int n, m, k, H[maxn], L[maxn], a[maxn][maxn];
int SumH[maxn], SumL[maxn];
namespace Max_Flow {
const int maxm = maxn * maxn * 2;
int to[maxm << 1], head[maxm], nxt[maxm << 1], w[maxm << 1], e = 1;
int dis[maxm], S, T;
void add(int x, int y, int z) {
to[++ e] = y;
nxt[e] = head[x];
head[x] = e;
w[e] = z;
}
bool bfs() {
queue<int> q;
For(i, 1, T) dis[i] = 0;
dis[S] = 1, q.push(S);
while(!q.empty()) {
int k = q.front(); q.pop();
go(k, i)
if(!dis[to[i]] && w[i]) {
dis[to[i]] = dis[k] + 1;
q.push(to[i]);
}
}
return dis[T];
}
int dfs(int x, int flow) {
if(x == T || !flow)
return flow;
int used = 0;
go(x, i)
if(dis[to[i]] == dis[x] + 1 && w[i]) {
int di = dfs(to[i], min(flow, w[i]));
w[i] -= di, w[i ^ 1] += di;
flow -= di, used += di;
if(!flow) break;
}
return used;
}
int solve()
{
int res = 0; S = n + m + 1, T = S + 1;
For(i, 1, n) add(S, i, SumH[i] - H[i]), add(i, S, 0);
For(i, 1, m) add(i + n, T, SumL[i] - L[i]), add(T, i + n, 0);
For(i, 1, n)
For(j, 1, m)
if(!a[i][j])
add(i, j + n, 1), add(j + n, i, 0);
while(bfs())
while(true) {
int flow = dfs(S, inf);
res += flow;
if(!flow) break;
}
return res;
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("1458.in", "r", stdin);
freopen("1458.out", "w", stdout);
#endif
int x, y, flag = 0;
cin >> n >> m >> k;
For(i, 1, n) scanf("%d", &H[i]), SumH[i] = m;
For(i, 1, m) scanf("%d", &L[i]), SumL[i] = n;
For(i, 1, k) {
scanf("%d%d", &x, &y);
-- SumH[x], -- SumL[y];
if(SumH[x] < H[x] || SumL[y] < L[y])
flag = 1;
a[x][y] = true;
}
if(flag) {
puts("JIONG!");
return 0;
}
printf("%d\n", n * m - k - Max_Flow::solve());
return 0;
}