# [SMOJ1894]战争

//1894.cpp
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>

using namespace std;

const int MAXN = 50 + 10;
const int MAXM = 50 + 10;
const int MAXK = 50 + 10;
const int INF = 0x3f3f3f3f;

typedef pair <int, int> pii;

struct Edge {
Edge *next;
int cap;
int dest;
} edges[(MAXM + MAXK + MAXM * MAXK) << 1], *current, *first_edge[MAXM + MAXK];

int N, M, K, L, s, t;
pii pt[MAXN], jd[MAXM], fdz[MAXK];
bool vis[MAXM + MAXK];

inline int sqr(int x) { return x * x; }

inline int dist1(pii a, pii b) { return sqr(a.first - b.first) + sqr(a.second - b.second); } //欧几里德距离的平方

inline double dist2(pii a, pii b) { return sqrt(dist1(a, b)); };

Edge *counterpart(Edge *x) { return edges + ((x - edges) ^ 1); }

void insert(int u, int v, int c) {
current -> next = first_edge[u];
current -> cap = c;
current -> dest = v;
first_edge[u] = current ++;
}

int dfs(int u, int f) {
if (u == t) return f;
if (vis[u]) return 0; else vis[u] = true;
for (Edge *p = first_edge[u]; p; p = p -> next)
if (p -> cap)
if (int res = dfs(p -> dest, min(f, p -> cap))) {
p -> cap -= res;
counterpart(p) -> cap += res;
return res;
}
return 0;
}

int main(void) {
freopen("1894.in", "r", stdin);
freopen("1894.out", "w", stdout);
scanf("%d%d%d%d", &N, &M, &K, &L);
for (int i = 0; i < N; i++) scanf("%d", &pt[i].first); //不得不吐槽这个恶心的输入格式
for (int i = 0; i < N; i++) scanf("%d", &pt[i].second);
for (int i = 0; i < M; i++) scanf("%d", &jd[i].first);
for (int i = 0; i < M; i++) scanf("%d", &jd[i].second);
for (int i = 0; i < K; i++) scanf("%d", &fdz[i].first);
for (int i = 0; i < K; i++) scanf("%d", &fdz[i].second);

s = 0; t = M + K + 1; current = edges;
fill(first_edge, first_edge + t + 1, (Edge*)0);
for (int i = 0; i < M; i++) {
int d = dist1(pt[0], jd[i]);
for (int j = 1; j < N; j++) d = min(d, dist1(pt[j], jd[i])); //取击毁当前基地所耗能量最小的基地
insert(s, i + 1, d); insert(i + 1, s, 0);
}
for (int i = 0; i < M; i++) //建立二分图
for (int j = 0; j < K; j++) if (dist2(jd[i], fdz[j]) <= L) insert(i + 1, M + j + 1, INF), insert(M + j + 1, i + 1, 0);
for (int i = 0; i < K; i++) {
int d = dist1(pt[0], fdz[i]);
for (int j = 1; j < N; j++) d = min(d, dist1(pt[j], fdz[i]));
insert(M + i + 1, t, d); insert(t, M + i + 1, 0);
}
int ans = 0;
while (true) {
memset(vis, false, sizeof vis);
if (int res = dfs(s, INF)) ans += res; else break;
}
printf("%d\n", ans);
return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120