这道题有两个坑点:第一,自己还是对很多算法的原理及其实现过程不够了解,只学会了机械性的套用。当有多个源点需要寻找最值时,其实解决方法就是将多个源点在BFS前同时加入队列即可,每个源点进行BFS也即层序遍历时,碰到终点,便会对结果进行处理,便轮不到距离较远的那些点来处理这个终点。。还是太菜了。。。以后一定多剖析深层次的东西。。。
第二个就是,最后结果的范围:根据题目给的范围我们可以知道极限情况下,图为1000*1000的矩阵,假设我们只有一个分店在图的一个角上,有n^2也即1e6个客户在分店的对角上,每个客户的订餐量为1000,那么就会有1e9份餐需要订,而此时分店到这1e6个客户所在位置的最短距离为对角线1000步,即最后的结果为1e12。这便远远超过了int,我们的结果用int存肯定是不行的,就需要用到long long。
以后一定多注意这种题目给的数据背后隐藏的东西啊,不然写半天因为这种原因被扣分也太亏了。。。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <string.h>
using namespace std;
typedef long long LL;
struct direct{
int drow, dcol;
}direct[4] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
struct node{
int x, y, s;
node(){}
node(int xx, int yy, int ss)
{
x = xx;
y = yy;
s = ss;
}
};
queue<node> q;
int n, m, k, d, x1, y1, c1, b[1100][1100], vis[1100][1100];
LL ans = 0;
void bfs()
{
while(!q.empty())
{
node f = q.front();
q.pop();
for(int i = 0 ; i < 4 ; ++i)
{
int nextrow = f.x + direct[i].drow;
int nextcol = f.y + direct[i].dcol;
if(nextrow >= 1 && nextrow <= n && nextcol >= 1 && nextcol <= n && !vis[nextrow][nextcol])
{
vis[nextrow][nextcol] = 1;
if(b[nextrow][nextcol])
ans += (f.s+1)*b[nextrow][nextcol];
node no;
no.x = nextrow;
no.y = nextcol;
no.s = f.s + 1;
q.push(no);
}
}
}
}
int main()
{
cin>>n>>m>>k>>d;
node no;
for(int i = 0 ; i < m ; ++i)
{
cin>>no.x>>no.y;
vis[no.x][no.y] = 1;
no.s = 0;
q.push(no);
}
for(int i = 0 ; i < k ; ++i)
{
cin>>x1>>y1>>c1;
b[x1][y1] += c1;
}
for(int i = 0 ; i < d ; ++i)
{
cin>>x1>>y1;
vis[x1][y1] = 1;
}
bfs();
cout<<ans;
}