【思路】
多个起点同时四周扩展广搜,注意会爆int
【AC】
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<map> 9 #include<stack> 10 using namespace std; 11 typedef long long ll; 12 const int maxn=1e3+2; 13 int n,m,k,d; 14 int mp[maxn][maxn]; 15 bool vis[maxn][maxn]; 16 int dis[maxn][maxn]; 17 struct node{ 18 int x; 19 int y; 20 int step; 21 node(int _x,int _y,int _s):x(_x),y(_y),step(_s){} 22 }; 23 int cnt; 24 int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; 25 queue<node> Q; 26 void init(){ 27 while(!Q.empty()) Q.pop(); 28 memset(mp,0,sizeof(mp)); 29 memset(vis,false,sizeof(vis)); 30 memset(dis,0,sizeof(dis)); 31 cnt=0; 32 } 33 bool check(int x,int y){ 34 if(x>=1&&x<=n&&y>=1&&y<=n) return true; 35 return false; 36 } 37 void bfs(){ 38 while(!Q.empty()){ 39 node q=Q.front(); 40 Q.pop(); 41 if(vis[q.x][q.y]) continue; 42 vis[q.x][q.y]=true; 43 if(mp[q.x][q.y]>0){ 44 dis[q.x][q.y]=q.step; 45 cnt++; 46 if(cnt==k) return; 47 } 48 for(int i=0;i<4;i++){ 49 int x=q.x+dir[i][0]; 50 int y=q.y+dir[i][1]; 51 if(check(x,y)&&mp[x][y]!=-1){ 52 Q.push(node(x,y,q.step+1)); 53 } 54 } 55 } 56 } 57 ll work(){ 58 bfs(); 59 ll ans=0; 60 for(int i=1;i<=n;i++){ 61 for(int j=1;j<=n;j++){ 62 if(mp[i][j]>0){ 63 ans+=(ll)mp[i][j]*(ll)dis[i][j]; 64 } 65 } 66 } 67 return ans; 68 } 69 int main(){ 70 while(~scanf("%d%d%d%d",&n,&m,&k,&d)){ 71 init(); 72 int x,y,c; 73 for(int i=1;i<=m;i++){ 74 scanf("%d%d",&x,&y); 75 Q.push(node(x,y,0)); 76 } 77 for(int i=1;i<=k;i++){ 78 scanf("%d%d%d",&x,&y,&c); 79 mp[x][y]+=c; 80 } 81 for(int i=1;i<=d;i++){ 82 scanf("%d%d",&x,&y); 83 mp[x][y]=-1; 84 } 85 ll ans=work(); 86 printf("%lld ",ans); 87 } 88 return 0; 89 }