201409-4 最优配餐
思路:
这道题很明显使用BFS,因为BFS同时具有最短路径的特征,所以直接使用BFS即可
反思:
但是自己毕竟写图论的题目比较少,很多实现的细节没做好,导致最后只有30分。
总结如下:
1.如果是图中不可访问的点,那么直接将他设置为VISITED即可
2.由于BFS是每一层每一层增加的,所以对于多个起点,我们可以在一开始的时候就将他们全部加入队列,这样相当于同时从两个点开始遍历图,而不需要遍历多次
3.在写题目的时候一定要想好思路,同时计算复杂度,讲真的每一个顶点都遍历一次图这种操作自己回想起来都觉得离谱好笑,这必定超时啊
代码:
#include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <unordered_set> #include <map> #include <queue> using namespace std; typedef struct{ int x,y,cost; }node; bool visited[1001][1001]; int w[1001][1001]; int dir[4][2] = {1,0,0,1,-1,0,0,-1}; queue<node> q; int n,m,k,d; long long int bfs(){ long long int sum = 0; int cnt = 0; while(!q.empty()){ node p = q.front(); q.pop(); int nowcost = p.cost + 1; for(int i = 0;i<4;i++){ int x = p.x + dir[i][0]; int y = p.y + dir[i][1]; if(!visited[x][y] && x >= 1 && x <= n && y >= 1 && y <= n){ visited[x][y] = true; q.push({x, y, nowcost}); if(w[x][y] != 0){ sum += w[x][y] * nowcost; if(++cnt == k){ return sum; } } } } } } int main(){ cin>>n>>m>>k>>d; for(int i = 0;i<m;i++){ int x; int y; cin>>x>>y; q.push({x, y, 0}); visited[x][y] = true; } for(int i = 0;i<k;i++){ int x; int y; int cost; cin>>x>>y>>cost; w[x][y] = cost; } for(int i = 0;i<d;i++){ int x,y; cin>>x>>y; visited[x][y] = true; } printf("%lld\n", bfs()); }