栋栋最近开了一家餐饮连锁店,提供外卖服务。
随着连锁店越来越多,怎么合理的给客户送餐成为了一个急需解决的问题。
栋栋的连锁店所在的区域可以看成是一个 n × n n×n n×n 的方格图(如下图所示),方格的格点上的位置上可能包含栋栋的分店(绿色标注)或者客户(蓝色标注),有一些格点是不能经过的(红色标注)。
方格图中的线表示可以行走的道路,相邻两个格点的距离为 1 1 1。
栋栋要送餐必须走可以行走的道路,而且不能经过红色标注的点。
送餐的主要成本体现在路上所花的时间,每一份餐每走一个单位的距离需要花费
1
1
1 块钱。
每个客户的需求都可以由栋栋的任意分店配送,每个分店没有配送总量的限制。
现在你得到了栋栋的客户的需求,请问在最优的送餐方式下,送这些餐需要花费多大的成本。
输入格式
输入的第一行包含四个整数
n
,
m
,
k
,
d
n,m,k,d
n,m,k,d,分别表示方格图的大小、栋栋的分店数量、客户的数量,以及不能经过的点的数量。
接下来 m m m 行,每行两个整数 x i , y i x_i,y_i xi,yi,表示栋栋的一个分店在方格图中的横坐标和纵坐标。
接下来 k k k 行,每行三个整数 x i , y i , c i x_i,y_i,c_i xi,yi,ci,分别表示每个客户在方格图中的横坐标、纵坐标和订餐的量。(注意,可能有多个客户在方格图中的同一个位置)
接下来 d d d 行,每行两个整数,分别表示每个不能经过的点的横坐标和纵坐标。
输出格式
输出一个整数,表示最优送餐方式下所需要花费的成本。
数据范围
所
有
评
测
用
例
都
满
足
:
1
≤
n
≤
1000
,
1
≤
m
,
k
,
d
≤
n
2
。
可
能
有
多
个
客
户
在
同
一
个
格
点
上
。
所有评测用例都满足:1≤n≤1000,1≤m,k,d≤n^2。可能有多个客户在同一个格点上。
所有评测用例都满足:1≤n≤1000,1≤m,k,d≤n2。可能有多个客户在同一个格点上。
每
个
客
户
的
订
餐
量
不
超
过
1000
,
每
个
客
户
所
需
要
的
餐
都
能
被
送
到
。
每个客户的订餐量不超过 1000,每个客户所需要的餐都能被送到。
每个客户的订餐量不超过1000,每个客户所需要的餐都能被送到。
输入样例:
10 2 3 3
1 1
8 8
1 5 1
2 3 3
6 7 2
1 2
2 2
6 8
输出样例:
29
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
const int maxn = 1010;
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};
int n, m, k, d;
bool a[maxn][maxn];
int dis[maxn][maxn];
ll ans;
map<pair<int, int>, int> ma;
int x[maxn * maxn], y[maxn * maxn];
template<typename T>
inline void read(T &x) {
x = 0;
char ch = getchar();
int f = 1;
while (!isdigit(ch)) {
if (ch == '-') f = -f;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << 3) + (x << 1) + ch - '0';
ch = getchar();
}
x = x * f;
}
void bfs(int x, int y) {
queue<pair<int, int> > q;
q.push({x, y});
dis[x][y] = 0;
while (!q.empty()) {
int x = q.front().first, y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (nx >= 1 && nx <= n && ny >= 1 && ny <= n && dis[nx][ny] > dis[x][y] + 1 && !a[nx][ny]) {
dis[nx][ny] = dis[x][y] + 1;
q.push({nx, ny});
}
}
}
}
int main() {
memset(dis, 0x3f, sizeof(dis));
read(n);
read(m);
read(k);
read(d);
for (int i = 1; i <= m; i++) {
read(x[i]);
read(y[i]);
}
for (int i = 1, x, y, c; i <= k; i++) {
read(x);
read(y);
read(c);
ma[{x, y}] += c;
}
for (int i = 1, x, y; i <= d; i++) {
read(x);
read(y);
a[x][y] = true;
}
for (int i = 1; i <= m; i++) {
bfs(x[i], y[i]);
}
for (auto &it:ma) {
ans += 1ll * dis[it.first.first][it.first.second] * it.second;
}
printf("%lld\n", ans);
return 0;
}