$读入数量庞大,必须用scanf读入$
$cin已经TLE了$
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
#define x first
#define y second
using namespace std;
const int M = 1e6+10, N = 1010;
typedef pair<int, int> PII;
typedef pair<PII, int> PIII;
typedef long long LL;
PIII s[M]; //存放客户信息
PII h[M]; //存放分店位置信息
int g[N][N];
int dist[N][N];
int n, m, k, d;
LL ans; //答案记得开long long
void bfs()
{
int dx[] = {1,0,-1,0}, dy[] = {0,-1,0,1};
queue<PII> q;
for(auto t : h){ //将所有分店入队
q.push(t);
dist[t.x][t.y] = 0;
}
while(q.size())
{
auto t = q.front();
q.pop();
for(int i = 0; i < 4; i ++)
{
int a = t.x + dx[i], b = t.y + dy[i];
if(a < 1 || a > n || b < 1 || b > n) continue;
if(g[a][b] || dist[a][b] != -1) continue;
dist[a][b] = dist[t.x][t.y] + 1;
q.push({a, b});
}
}
for(auto t : s){ //最后将到达每个客户的最短距离乘上订单数,再求和即为答案
ans += dist[t.x.x][t.x.y] * t.y;
}
}
int main()
{
memset(dist, -1, sizeof dist);
scanf("%d%d%d%d",&n, &m, &k, &d);
for(int i = 0; i < m; i ++){ //读入分店位置
int a, b;
scanf("%d%d",&a, &b);
h[i] = {a, b};
}
for(int i = 0; i < k; i ++){ //读入客户信息
int a, b, v;
scanf("%d%d%d",&a, &b, &v);
s[i] = {{a, b}, v};
}
for(int i = 0; i < d; i ++){ //读入不能走的坐标
int a, b;
scanf("%d%d",&a, &b);
g[a][b] = 1; // 1 表示不能走
}
bfs();
cout << ans << endl;
return 0;
}