判断星球之间的长度满足小于等于飞船的油量,防御力小于等于飞船下的攻击力,则建边,最后求最大匹配;
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#pragma warning(disable:4996)
using namespace std;
typedef long long ll;
const int maxn = 2000005;
int head[maxn], ver[maxn], nex[maxn];
int dis[2005][2005];
const int INF = 0x3f3f3f3f;
int s, b, k, h;
int vis[maxn];
int xs[maxn], a[maxn], f[maxn];
int xb[maxn], c[maxn];
int match[maxn];
int cnt;
int n, m;
void add(int x, int y) {
ver[cnt] = y;
nex[cnt] = head[x];
head[x] = cnt++;
}
void floy(int n) {
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
}
}
}
}
int dfs(int x) {
for (int i = head[x]; i != -1; i = nex[i]) {
int v = ver[i];
if (!vis[v]) {
vis[v] = 1;
if (!match[v] || dfs(match[v])) {
match[v] = x;
return true;
}
}
}
return false;
}
int main() {
scanf("%d%d", &n, &m);
memset(dis, INF, sizeof(dis));
for (int i = 1; i <= m; i++) {
int x, y;
scanf("%d%d", &x, &y);
dis[x][y] = dis[y][x] = 1;
}
for (int i = 1; i <= n; i++) {
dis[i][i] = 0;
}
floy(n);
memset(head, -1, sizeof(head));
scanf("%d%d%d%d", &s, &b, &k, &h);
for (int i = 1; i <= s; i++) {
scanf("%d%d%d", &xs[i], &a[i], &f[i]);
}
for (int i = 1; i <= b; i++) {
scanf("%d%d", &xb[i], &c[i]);
}
for (int i = 1; i <= s; i++) {
for (int j = 1; j <= b; j++) {
if (dis[xs[i]][xb[j]] <= f[i] && c[j] <= a[i]) {
add(i,j);
}
}
}
ll ans = 0;
for (int i = 1; i <= s; i++) {
memset(vis, 0, sizeof(vis));
if (dfs(i)) {
ans++;
}
}
ll ans1 = (ll)s * h;
ll ans2 = (ll)ans * k;
printf("%lld\n", min(ans1, ans2));
return 0;
}